From 1a4b37243e7a55eff0e123aa1493e49db39962e7 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:10:21 -0300 Subject: [PATCH 001/114] add service usage consumer role to SA's --- 0-bootstrap/sa.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/0-bootstrap/sa.tf b/0-bootstrap/sa.tf index da23168b0..ac849dafe 100644 --- a/0-bootstrap/sa.tf +++ b/0-bootstrap/sa.tf @@ -49,14 +49,18 @@ locals { "roles/resourcemanager.tagUser", "roles/cloudasset.owner", "roles/securitycenter.sourcesEditor", + "roles/serviceusage.serviceUsageConsumer", ], local.common_roles)), "env" = distinct(concat([ + "roles/accesscontextmanager.policyAdmin", "roles/resourcemanager.tagUser", "roles/assuredworkloads.admin", + "roles/serviceusage.serviceUsageConsumer", ], local.common_roles)), "net" = distinct(concat([ "roles/accesscontextmanager.policyAdmin", "roles/compute.xpnAdmin", + "roles/serviceusage.serviceUsageConsumer", ], local.common_roles)), "proj" = distinct(concat([ "roles/accesscontextmanager.policyAdmin", From 21f33bbc066fe4b24b9fa723c600ca2b4e5d4afa Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:11:49 -0300 Subject: [PATCH 002/114] add cicd and seed output prjs numbers --- 0-bootstrap/README.md | 3 +++ 0-bootstrap/cb.tf | 5 +++++ 0-bootstrap/main.tf | 5 +++++ 0-bootstrap/outputs.tf | 15 +++++++++++++++ 4 files changed, 28 insertions(+) diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md index 15a339411..87baa2a0b 100644 --- a/0-bootstrap/README.md +++ b/0-bootstrap/README.md @@ -546,6 +546,7 @@ The following steps will guide you through deploying without using Cloud Build. | cloud\_build\_worker\_range\_id | The Cloud Build private worker IP range ID. | | cloud\_builder\_artifact\_repo | Artifact Registry (AR) Repository created to store TF Cloud Builder images. | | cloudbuild\_project\_id | Project where Cloud Build configuration and terraform container image will reside. | +| cloudbuild\_project\_number | The cloudbuild project number. | | common\_config | Common configuration data to be used in other steps. | | csr\_repos | List of Cloud Source Repos created by the module, linked to Cloud Build triggers. | | environment\_step\_terraform\_service\_account\_email | Environment Step Terraform Account | @@ -555,9 +556,11 @@ The following steps will guide you through deploying without using Cloud Build. | networks\_step\_terraform\_service\_account\_email | Networks Step Terraform Account | | optional\_groups | List of Google Groups created that are optional to the Example Foundation steps. | | organization\_step\_terraform\_service\_account\_email | Organization Step Terraform Account | +| parent\_id | Parent ID service account. | | projects\_gcs\_bucket\_tfstate | Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project. | | projects\_step\_terraform\_service\_account\_email | Projects Step Terraform Account | | required\_groups | List of Google Groups created that are required by the Example Foundation steps. | | seed\_project\_id | Project where service accounts and core APIs will be enabled. | +| seed\_project\_number | The seed project number. | diff --git a/0-bootstrap/cb.tf b/0-bootstrap/cb.tf index 8707e2ed3..216442c38 100644 --- a/0-bootstrap/cb.tf +++ b/0-bootstrap/cb.tf @@ -272,3 +272,8 @@ resource "google_sourcerepo_repository_iam_member" "member" { role = "roles/viewer" member = "serviceAccount:${google_service_account.terraform-env-sa[each.key].email}" } + +data "google_project" "cloudbuild_project" { + project_id = module.tf_source.cloudbuild_project_id + depends_on = [module.tf_source] +} diff --git a/0-bootstrap/main.tf b/0-bootstrap/main.tf index 44ca2faf0..81d7e634f 100644 --- a/0-bootstrap/main.tf +++ b/0-bootstrap/main.tf @@ -106,3 +106,8 @@ module "seed_bootstrap" { depends_on = [module.required_group] } + +data "google_project" "seed_project" { + project_id = module.seed_bootstrap.seed_project_id + depends_on = [module.seed_bootstrap] +} diff --git a/0-bootstrap/outputs.tf b/0-bootstrap/outputs.tf index 01e6fe09b..0dd7b7239 100644 --- a/0-bootstrap/outputs.tf +++ b/0-bootstrap/outputs.tf @@ -71,6 +71,11 @@ output "common_config" { } } +output "parent_id" { + description = "Parent ID service account." + value = var.parent_folder != "" ? "folder-${local.parent_id}" : "org-${var.org_id}" +} + output "required_groups" { description = "List of Google Groups created that are required by the Example Foundation steps." value = var.groups.create_required_groups == false ? tomap(var.groups.required_groups) : tomap({ for key, value in module.required_group : key => value.id }) @@ -81,6 +86,16 @@ output "optional_groups" { value = var.groups.create_optional_groups == false ? tomap(var.groups.optional_groups) : tomap({ for key, value in module.optional_group : key => value.id }) } +output "seed_project_number" { + description = "The seed project number." + value = data.google_project.seed_project.number +} + +output "cloudbuild_project_number" { + description = "The cloudbuild project number." + value = data.google_project.cloudbuild_project.number +} + /* ---------------------------------------- Specific to cloudbuild_module ---------------------------------------- */ From aee66cbc8f7273fcf979829842fdebf52013f8cf Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:12:22 -0300 Subject: [PATCH 003/114] add cloud nat --- 0-bootstrap/modules/cb-private-pool/README.md | 2 +- .../modules/cb-private-pool/network.tf | 232 ++++++++++++++++-- .../modules/cb-private-pool/variables.tf | 6 +- 3 files changed, 218 insertions(+), 22 deletions(-) diff --git a/0-bootstrap/modules/cb-private-pool/README.md b/0-bootstrap/modules/cb-private-pool/README.md index 1e6969997..9411e7db5 100644 --- a/0-bootstrap/modules/cb-private-pool/README.md +++ b/0-bootstrap/modules/cb-private-pool/README.md @@ -3,7 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| private\_worker\_pool | name: Name of the worker pool. A name with a random suffix is generated if not set.
region: The private worker pool region. See https://cloud.google.com/build/docs/locations for available locations.
disk\_size\_gb: Size of the disk attached to the worker, in GB.
machine\_type: Machine type of a worker.
no\_external\_ip: If true, workers are created without any public address, which prevents network egress to public IPs.
enable\_network\_peering: Set to true to enable configuration of networking peering for the private worker pool.
create\_peered\_network: If true a network will be created to stablish the network peering.
peered\_network\_id: The ID of the existing network to configure peering for the private worker pool if create\_peered\_network false. The project containing the network must have Service Networking API (`servicenetworking.googleapis.com`) enabled.
peered\_network\_subnet\_ip: The IP range to be used for the subnet that a will created in the peered network if create\_peered\_network true.
peering\_address: The IP address or beginning of the peering address range. This can be supplied as an input to reserve a specific address or omitted to allow GCP to choose a valid one.
peering\_prefix\_length: The prefix length of the IP peering range. If not present, it means the address field is a single IP address. |
object({
name = optional(string, "")
region = optional(string, "us-central1")
disk_size_gb = optional(number, 100)
machine_type = optional(string, "e2-medium")
no_external_ip = optional(bool, false)
enable_network_peering = optional(bool, false)
create_peered_network = optional(bool, false)
peered_network_id = optional(string, "")
peered_network_subnet_ip = optional(string, "")
peering_address = optional(string, null)
peering_prefix_length = optional(number, 24)
})
| `{}` | no | +| private\_worker\_pool | name: Name of the worker pool. A name with a random suffix is generated if not set.
region: The private worker pool region. See https://cloud.google.com/build/docs/locations for available locations.
disk\_size\_gb: Size of the disk attached to the worker, in GB.
machine\_type: Machine type of a worker.
no\_external\_ip: If true, workers are created without any public address, which prevents network egress to public IPs.
enable\_network\_peering: Set to true to enable configuration of networking peering for the private worker pool.
create\_peered\_network: If true a network will be created to stablish the network peering.
peered\_network\_id: The ID of the existing network to configure peering for the private worker pool if create\_peered\_network false. The project containing the network must have Service Networking API (`servicenetworking.googleapis.com`) enabled.
peered\_network\_subnet\_ip: The IP range to be used for the subnet that a will created in the peered network if create\_peered\_network true.
peering\_address: The IP address or beginning of the peering address range. This can be supplied as an input to reserve a specific address or omitted to allow GCP to choose a valid one.
peering\_prefix\_length: The prefix length of the IP peering range. If not present, it means the address field is a single IP address. |
object({
name = optional(string, "")
region = optional(string, "us-central1")
disk_size_gb = optional(number, 100)
machine_type = optional(string, "e2-medium")
no_external_ip = optional(bool, true)
enable_network_peering = optional(bool, true)
create_peered_network = optional(bool, true)
peered_network_id = optional(string, "")
peered_network_subnet_ip = optional(string, "")
peering_address = optional(string, null)
peering_prefix_length = optional(number, 24)
})
| `{}` | no | | project\_id | ID of the project where the private pool will be created | `string` | n/a | yes | | vpc\_flow\_logs | aggregation\_interval: Toggles the aggregation interval for collecting flow logs. Increasing the interval time will reduce the amount of generated flow logs for long lasting connections. Possible values are: INTERVAL\_5\_SEC, INTERVAL\_30\_SEC, INTERVAL\_1\_MIN, INTERVAL\_5\_MIN, INTERVAL\_10\_MIN, INTERVAL\_15\_MIN.
flow\_sampling: Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported. The value of the field must be in [0, 1].
metadata: Configures whether metadata fields should be added to the reported VPC flow logs. Possible values are: EXCLUDE\_ALL\_METADATA, INCLUDE\_ALL\_METADATA, CUSTOM\_METADATA.
metadata\_fields: ist of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and "metadata" is set to CUSTOM\_METADATA.
filter\_expr: Export filter used to define which VPC flow logs should be logged, as as CEL expression. See https://cloud.google.com/vpc/docs/flow-logs#filtering for details on how to format this field. |
object({
aggregation_interval = optional(string, "INTERVAL_5_SEC")
flow_sampling = optional(string, "0.5")
metadata = optional(string, "INCLUDE_ALL_METADATA")
metadata_fields = optional(list(string), [])
filter_expr = optional(string, "true")
})
| `{}` | no | | vpn\_configuration | enable\_vpn: set to true to create VPN connection to on prem. If true, the following values must be valid.
on\_prem\_public\_ip\_address0: The first public IP address for on prem VPN connection.
on\_prem\_public\_ip\_address1: The second public IP address for on prem VPN connection.
router\_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for cloud routes.
bgp\_peer\_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for peer cloud routes.
shared\_secret: The shared secret used in the VPN.
psk\_secret\_project\_id: The ID of the project that contains the secret from secret manager that holds the VPN pre-shared key.
psk\_secret\_name: The name of the secret to retrieve from secret manager that holds the VPN pre-shared key.
tunnel0\_bgp\_peer\_address: BGP peer address for tunnel 0.
tunnel0\_bgp\_session\_range: BGP session range for tunnel 0.
tunnel1\_bgp\_peer\_address: BGP peer address for tunnel 1.
tunnel1\_bgp\_session\_range: BGP session range for tunnel 1. |
object({
enable_vpn = optional(bool, false)
on_prem_public_ip_address0 = optional(string, "")
on_prem_public_ip_address1 = optional(string, "")
router_asn = optional(number, 64515)
bgp_peer_asn = optional(number, 64513)
psk_secret_project_id = optional(string, "")
psk_secret_name = optional(string, "")
tunnel0_bgp_peer_address = optional(string, "")
tunnel0_bgp_session_range = optional(string, "")
tunnel1_bgp_peer_address = optional(string, "")
tunnel1_bgp_session_range = optional(string, "")
})
| `{}` | no | diff --git a/0-bootstrap/modules/cb-private-pool/network.tf b/0-bootstrap/modules/cb-private-pool/network.tf index ea5546675..fa014f932 100644 --- a/0-bootstrap/modules/cb-private-pool/network.tf +++ b/0-bootstrap/modules/cb-private-pool/network.tf @@ -16,6 +16,26 @@ locals { peered_ip_range = var.private_worker_pool.enable_network_peering ? "${google_compute_global_address.worker_pool_range[0].address}/${google_compute_global_address.worker_pool_range[0].prefix_length}" : "" + + nat_proxy_vm_ip_range = "10.1.1.0/24" + + single_project_network = { + subnet_name = "eab-develop-us-central1" + subnet_ip = "10.1.20.0/24" + subnet_region = "us-central1" + subnet_private_access = true + } + single_project_secondary = { + "eab-develop-us-central1" = [ + { + range_name = "eab-develop-us-central1-secondary-01" + ip_cidr_range = "192.168.0.0/18" + }, + { + range_name = "eab-develop-us-central1-secondary-02" + ip_cidr_range = "192.168.64.0/18" + }, + ] } } module "peered_network" { @@ -96,27 +116,203 @@ module "firewall_rules" { project_id = var.project_id network_name = local.peered_network_id - rules = [{ - name = "fw-b-cbpools-100-i-a-all-all-all-service-networking" - description = "allow ingres from the IPs configured for service networking" - direction = "INGRESS" - priority = 100 - source_tags = null - source_service_accounts = null - target_tags = null - target_service_accounts = null + rules = [ + { + name = "fw-b-cbpools-100-i-a-all-all-all-service-networking" + description = "Allow ingress from the IPs configured for service networking" + direction = "INGRESS" + priority = 100 + source_tags = null + source_service_accounts = null + target_tags = null + target_service_accounts = null + + ranges = [local.peered_ip_range] + + allow = [{ + protocol = "all" + ports = null + }] + + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + }, + { + name = "allow-pool-to-nat" + description = "Allow all from worker pool to NAT gateway" + direction = "INGRESS" + priority = 1000 + source_tags = null + source_service_accounts = null + target_tags = ["nat-gateway"] + target_service_accounts = null + + ranges = ["${google_compute_global_address.worker_pool_range[0].address}/${google_compute_global_address.worker_pool_range[0].prefix_length}"] + + allow = [{ + protocol = "all" + ports = null + }] + + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + }, + { + name = "allow-icmp" + description = "Allow ICMP from anywhere" + direction = "INGRESS" + priority = 65534 + source_tags = null + source_service_accounts = null + target_tags = null + target_service_accounts = null - ranges = [local.peered_ip_range] + ranges = ["0.0.0.0/1"] + + allow = [{ + protocol = "icmp" + ports = null + }] + + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + }, + { + name = "allow-ssh-ingress" + description = "Allow SSH from anywhere (0.0.0.0/1)" + direction = "INGRESS" + priority = 1000 + source_tags = null + source_service_accounts = null + target_tags = null + target_service_accounts = null + + ranges = ["0.0.0.0/1"] + + allow = [{ + protocol = "tcp" + ports = ["22"] + }] + + deny = [] + + log_config = { + metadata = "INCLUDE_ALL_METADATA" + } + } + ] +} + +resource "google_compute_address" "cloud_build_nat" { + project = var.project_id + address_type = "EXTERNAL" + name = "cloud-build-nat" + network_tier = "PREMIUM" + region = "us-central1" +} - allow = [{ - protocol = "all" - ports = null - }] +resource "google_compute_instance" "vm-proxy" { + project = var.project_id + name = "cloud-build-nat-vm" + machine_type = "e2-medium" + zone = "us-central1-a" - deny = [] + tags = ["direct-gateway-access", "nat-gateway"] - log_config = { - metadata = "INCLUDE_ALL_METADATA" + boot_disk { + initialize_params { + image = "debian-cloud/debian-12" } - }] + } + + network_interface { + network = local.peered_network_name + subnetwork = "sb-b-cbpools-${var.private_worker_pool.region}" + subnetwork_project = var.project_id + + } + + can_ip_forward = true + + // This script configures the VM to do IP Forwarding + metadata_startup_script = "sysctl -w net.ipv4.ip_forward=1 && iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE" + + service_account { + scopes = ["cloud-platform"] + } + + depends_on = [resource.google_compute_router_nat.cb-nat] +} + +# This route will route packets to the NAT VM +resource "google_compute_route" "through-nat" { + name = "through-nat-range1" + project = var.project_id + dest_range = "0.0.0.0/1" + network = local.peered_network_name + next_hop_instance = google_compute_instance.vm-proxy.id + priority = 10 +} + +resource "google_compute_route" "through-nat2" { + name = "through-nat-range2" + project = var.project_id + dest_range = "128.0.0.0/1" + network = local.peered_network_name + next_hop_instance = google_compute_instance.vm-proxy.id + priority = 10 +} + +# This route allow the NAT VM to reach the internet with it's external IP address + +resource "google_compute_route" "direct-to-gateway" { + name = "direct-to-gateway-range1" + project = var.project_id + dest_range = "0.0.0.0/1" + network = local.peered_network_name + next_hop_gateway = "default-internet-gateway" + tags = ["direct-gateway-access"] + priority = 5 +} + +resource "google_compute_route" "direct-to-gateway2" { + name = "direct-to-gateway-range2" + project = var.project_id + dest_range = "128.0.0.0/1" + network = local.peered_network_name + next_hop_gateway = "default-internet-gateway" + tags = ["direct-gateway-access"] + priority = 5 +} + +# Cloud Router +resource "google_compute_router" "cb-router" { + name = "cb-cloud-router" + network = local.peered_network_name + region = "us-central1" + project = var.project_id +} + +# Cloud NAT +resource "google_compute_router_nat" "cb-nat" { + project = var.project_id + name = "cb-cloud-nat" + router = google_compute_router.cb-router.name + region = google_compute_router.cb-router.region + nat_ip_allocate_option = "AUTO_ONLY" + source_subnetwork_ip_ranges_to_nat = "ALL_SUBNETWORKS_ALL_IP_RANGES" + + log_config { + enable = true + filter = "ALL" + } } diff --git a/0-bootstrap/modules/cb-private-pool/variables.tf b/0-bootstrap/modules/cb-private-pool/variables.tf index 5dfcbb6a0..1639223ce 100644 --- a/0-bootstrap/modules/cb-private-pool/variables.tf +++ b/0-bootstrap/modules/cb-private-pool/variables.tf @@ -38,9 +38,9 @@ variable "private_worker_pool" { region = optional(string, "us-central1") disk_size_gb = optional(number, 100) machine_type = optional(string, "e2-medium") - no_external_ip = optional(bool, false) - enable_network_peering = optional(bool, false) - create_peered_network = optional(bool, false) + no_external_ip = optional(bool, true) + enable_network_peering = optional(bool, true) + create_peered_network = optional(bool, true) peered_network_id = optional(string, "") peered_network_subnet_ip = optional(string, "") peering_address = optional(string, null) From 21b32d46230975e48414e72a94a3bcb6f48077bf Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:16:37 -0300 Subject: [PATCH 004/114] add service control module --- 1-org/modules/service_control/main.tf | 80 ++++++++++ 1-org/modules/service_control/outputs.tf | 35 +++++ 1-org/modules/service_control/variables.tf | 170 +++++++++++++++++++++ 1-org/modules/service_control/versions.tf | 42 +++++ 4 files changed, 327 insertions(+) create mode 100644 1-org/modules/service_control/main.tf create mode 100644 1-org/modules/service_control/outputs.tf create mode 100644 1-org/modules/service_control/variables.tf create mode 100644 1-org/modules/service_control/versions.tf diff --git a/1-org/modules/service_control/main.tf b/1-org/modules/service_control/main.tf new file mode 100644 index 000000000..a1f004910 --- /dev/null +++ b/1-org/modules/service_control/main.tf @@ -0,0 +1,80 @@ +/** + * Copyright 2025 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 { + prefix = "svpc" + access_level_name = "alp_${local.prefix}_members_${random_id.random_access_level_suffix.hex}" + access_level_name_dry_run = "alp_${local.prefix}_members_dry_run_${random_id.random_access_level_suffix.hex}" + perimeter_name = "sp_${local.prefix}_default_common_perimeter_${random_id.random_access_level_suffix.hex}" +} + +resource "random_id" "random_access_level_suffix" { + byte_length = 2 +} + +module "access_level" { + source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" + version = "~> 7.1.2" + + description = "${local.prefix} Access Level for use in an enforced perimeter" + policy = var.access_context_manager_policy_id + name = local.access_level_name + members = var.members +} + +module "access_level_dry_run" { + source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" + version = "~> 7.1.2" + + description = "${local.prefix} Access Level for testing with a dry run perimeter" + policy = var.access_context_manager_policy_id + name = local.access_level_name_dry_run + members = var.members_dry_run +} + +module "regular_service_perimeter" { + source = "git::https://github.com/mariammartins/terraform-google-vpc-service-controls.git//modules/regular_service_perimeter?ref=fix-ingress-rules" + # source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" + # version = "~> 7.1.2" + + policy = var.access_context_manager_policy_id + perimeter_name = local.perimeter_name + description = "Default VPC Service Controls perimeter" + + # configurations for a perimeter in enforced mode. + resources = var.enforce_vpcsc ? var.resources : [] + resource_keys = var.enforce_vpcsc ? var.resource_keys : [] + access_levels = var.enforce_vpcsc ? [module.access_level.name] : [] + restricted_services = var.enforce_vpcsc ? var.restricted_services : [] + vpc_accessible_services = var.enforce_vpcsc ? ["*"] : [] + ingress_policies = var.enforce_vpcsc ? var.ingress_policies : [] + egress_policies = var.enforce_vpcsc ? var.egress_policies : [] + + # configurations for a perimeter in dry run mode. + resources_dry_run = var.resources_dry_run + resource_keys_dry_run = var.resource_keys_dry_run + access_levels_dry_run = [module.access_level_dry_run.name] + restricted_services_dry_run = var.restricted_services_dry_run + vpc_accessible_services_dry_run = ["*"] + ingress_policies_dry_run = var.ingress_policies_dry_run + egress_policies_dry_run = var.egress_policies_dry_run +} + +resource "time_sleep" "wait_vpc_sc_propagation" { + create_duration = "60s" + + depends_on = [module.regular_service_perimeter] +} diff --git a/1-org/modules/service_control/outputs.tf b/1-org/modules/service_control/outputs.tf new file mode 100644 index 000000000..2609dc4ae --- /dev/null +++ b/1-org/modules/service_control/outputs.tf @@ -0,0 +1,35 @@ +/** + * Copyright 2025 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 "access_level_name" { + value = local.access_level_name + description = "Access context manager access level name for the enforced perimeter" +} + +output "access_level_name_dry_run" { + value = local.access_level_name_dry_run + description = "Access context manager access level name for the dry-run perimeter" +} + +output "enforce_vpcsc" { + value = var.enforce_vpcsc + description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." +} + +output "service_perimeter_name" { + value = local.perimeter_name + description = "Access context manager service perimeter name for the enforced perimeter" +} diff --git a/1-org/modules/service_control/variables.tf b/1-org/modules/service_control/variables.tf new file mode 100644 index 000000000..1236660be --- /dev/null +++ b/1-org/modules/service_control/variables.tf @@ -0,0 +1,170 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +variable "access_context_manager_policy_id" { + type = number + description = "The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." +} + +variable "members" { + type = list(string) + description = "An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" +} + +variable "members_dry_run" { + type = list(string) + description = "An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" +} + + +variable "restricted_services" { + type = list(string) + description = "List of services to restrict in an enforced perimeter." +} + +variable "restricted_services_dry_run" { + type = list(string) + description = "List of services to restrict in an enforced perimeter." +} + +variable "enforce_vpcsc" { + description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." + type = bool + default = false +} + +variable "ingress_policies_dry_run" { + description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + external_resources = optional(list(string), []) + }) + })) + default = [] +} + +variable "egress_policies_dry_run" { + description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + external_resources = optional(list(string), []) + }) + })) + default = [] +} + +variable "ingress_policies" { + description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + }) + })) + default = [] +} + +variable "egress_policies" { + description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + external_resources = optional(list(string), []) + }) + })) + default = [] +} + +variable "resources" { + description = "A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed." + type = list(string) + default = [] +} + +variable "resource_keys" { + description = "A list of keys to use for the Terraform state. The order should correspond to var.resources and the keys must not be dynamically computed. If `null`, var.resources will be used as keys." + type = list(string) + default = null +} + +variable "resources_dry_run" { + description = "A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set." + type = list(string) + default = [] +} + +variable "resource_keys_dry_run" { + description = "A list of keys to use for the Terraform state. The order should correspond to var.resources_dry_run and the keys must not be dynamically computed. If `null`, var.resources_dry_run will be used as keys." + type = list(string) + default = null +} diff --git a/1-org/modules/service_control/versions.tf b/1-org/modules/service_control/versions.tf new file mode 100644 index 000000000..c7d484d8a --- /dev/null +++ b/1-org/modules/service_control/versions.tf @@ -0,0 +1,42 @@ +/** + * Copyright 2025 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. + */ + +terraform { + required_version = ">= 0.13" + required_providers { + google = { + // version 6.26.0 removed because of the bug https://github.com/hashicorp/terraform-provider-google/issues/21950 + source = "hashicorp/google" + version = ">= 3.50, < 6.26.0" + } + google-beta = { + // version 6.26.0 removed because of the bug https://github.com/hashicorp/terraform-provider-google/issues/21950 + source = "hashicorp/google-beta" + version = ">= 3.50, < 6.26.0" + } + random = { + source = "hashicorp/random" + } + } + + provider_meta "google" { + module_name = "blueprints/terraform/terraform-example-foundation:restricted_shared_vpc/v4.1.0" + } + + provider_meta "google-beta" { + module_name = "blueprints/terraform/terraform-example-foundation:restricted_shared_vpc/v4.1.0" + } +} From ddc929b1ab943fe1203f26754ad67a6f0f3058d4 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:28:12 -0300 Subject: [PATCH 005/114] add cicd, seed and parent_id ouputs --- 1-org/envs/shared/remote.tf | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/1-org/envs/shared/remote.tf b/1-org/envs/shared/remote.tf index 9b54670c8..f514676cd 100644 --- a/1-org/envs/shared/remote.tf +++ b/1-org/envs/shared/remote.tf @@ -31,6 +31,14 @@ locals { bootstrap_folder_name = data.terraform_remote_state.bootstrap.outputs.common_config.bootstrap_folder_name cloud_build_private_worker_pool_id = try(data.terraform_remote_state.bootstrap.outputs.cloud_build_private_worker_pool_id, "") required_groups = data.terraform_remote_state.bootstrap.outputs.required_groups + organization_service_account = data.terraform_remote_state.bootstrap.outputs.organization_step_terraform_service_account_email + networks_service_account = data.terraform_remote_state.bootstrap.outputs.networks_step_terraform_service_account_email + projects_service_account = data.terraform_remote_state.bootstrap.outputs.projects_step_terraform_service_account_email + environment_service_account = data.terraform_remote_state.bootstrap.outputs.environment_step_terraform_service_account_email + cloudbuild_project_number = data.terraform_remote_state.bootstrap.outputs.cloudbuild_project_number + seed_project_id = data.terraform_remote_state.bootstrap.outputs.seed_project_id + seed_project_number = data.terraform_remote_state.bootstrap.outputs.seed_project_number + parent_id = data.terraform_remote_state.bootstrap.outputs.parent_id } data "terraform_remote_state" "bootstrap" { From 1651277f82a92a204f6ddfcff485db764753a2b1 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:29:36 -0300 Subject: [PATCH 006/114] add new nariables related to vpc-sc --- 1-org/envs/shared/variables.tf | 152 ++++++++++++++++++++++++++++++++- 1 file changed, 149 insertions(+), 3 deletions(-) diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index 1c1830366..5f368e27e 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -14,6 +14,12 @@ * limitations under the License. */ +variable "access_context_manager_policy_id" { + description = "The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." + type = string + default = "" +} + variable "enable_hub_and_spoke" { description = "Enable Hub-and-Spoke architecture." type = bool @@ -23,7 +29,7 @@ variable "enable_hub_and_spoke" { variable "enable_scc_resources_in_terraform" { description = "Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context." type = bool - default = false + default = true } variable "enable_kms_key_usage_tracking" { @@ -167,12 +173,12 @@ variable "essential_contacts_language" { } variable "remote_state_bucket" { - description = "Backend bucket to load Terraform Remote State Data from previous steps." + description = "Backend bucket to load Terraform Remote State Data from previous steps.." type = string } variable "essential_contacts_domains_to_allow" { - description = "The list of domains that email addresses added to Essential Contacts can have." + description = ".The list of domains that email addresses added to Essential Contacts can have." type = list(string) } @@ -199,3 +205,143 @@ variable "folder_deletion_protection" { type = string default = true } + +variable "custom_restricted_services" { + description = "List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." + type = list(string) + default = [] +} + +variable "custom_restricted_services_dry_run" { + description = "List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." + type = list(string) + default = [] +} + +variable "ingress_policies_dry_run" { + description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + }) + })) + default = [] +} + +variable "egress_policies_dry_run" { + description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + external_resources = optional(list(string), []) + }) + })) + default = [] +} + +variable "ingress_policies" { + description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + }) + })) + default = [] +} + +variable "egress_policies" { + description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" + type = list(object({ + title = optional(string, null) + from = object({ + sources = optional(object({ + resources = optional(list(string), []) + access_levels = optional(list(string), []) + }), {}), + identity_type = optional(string, null) + identities = optional(list(string), null) + }) + to = object({ + operations = optional(map(object({ + methods = optional(list(string), []) + permissions = optional(list(string), []) + })), {}), + roles = optional(list(string), null) + resources = optional(list(string), ["*"]) + external_resources = optional(list(string), []) + }) + })) + default = [] +} + +variable "perimeter_additional_members" { + description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." + type = list(string) + default = [] +} + +variable "perimeter_additional_members_dry_run" { + description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." + type = list(string) + default = [] +} + +variable "resources" { + description = "A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed." + type = list(string) + default = [] +} + +variable "resources_dry_run" { + description = "A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set." + type = list(string) + default = [] +} + +variable "enforce_vpcsc" { + description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." + type = bool + default = false +} From b701d6e92187706825dbbc842ad7758c0b569379 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:29:54 -0300 Subject: [PATCH 007/114] add perimeter adittional members variable --- 1-org/envs/shared/terraform.example.tfvars | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/1-org/envs/shared/terraform.example.tfvars b/1-org/envs/shared/terraform.example.tfvars index 9ff38bde8..7a2e3a69f 100644 --- a/1-org/envs/shared/terraform.example.tfvars +++ b/1-org/envs/shared/terraform.example.tfvars @@ -19,6 +19,11 @@ domains_to_allow = ["example.com"] essential_contacts_domains_to_allow = ["@example.com"] +// Update the following line and add you email in the perimeter_additional_members list. +// You must be in this list to be able to view/access resources in the project protected by the VPC service controls. + +perimeter_additional_members = ["user:YOUR-USER-EMAIL@example.com"] + scc_notification_name = "scc-notify" remote_state_bucket = "REMOTE_STATE_BUCKET" From d3771c46d303e6f5150de21be03d1549292fc23f Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:30:19 -0300 Subject: [PATCH 008/114] upd README --- 1-org/envs/shared/README.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 502720442..90e5a1dbc 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -3,25 +3,37 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | `""` | no | | billing\_export\_dataset\_location | The location of the dataset for billing data export. | `string` | `null` | no | | create\_access\_context\_manager\_access\_policy | Whether to create access context manager access policy. | `bool` | `true` | no | | create\_unique\_tag\_key | Creates unique organization-wide tag keys by adding a random suffix to each key. | `bool` | `false` | no | +| custom\_restricted\_services | List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | +| custom\_restricted\_services\_dry\_run | List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | domains\_to\_allow | The list of domains to allow users from in IAM. Used by Domain Restricted Sharing Organization Policy. Must include the domain of the organization you are deploying the foundation. To add other domains you must also grant access to these domains to the Terraform Service Account used in the deploy. | `list(string)` | n/a | yes | +| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
external_resources = optional(list(string), [])
})
}))
| `[]` | no | +| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
external_resources = optional(list(string), [])
})
}))
| `[]` | no | | enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_kms\_key\_usage\_tracking | Enable KMS centralized key usage tracking system. | `bool` | `true` | no | -| enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context. | `bool` | `false` | no | +| enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context. | `bool` | `true` | no | | enforce\_allowed\_worker\_pools | Whether to enforce the organization policy restriction on allowed worker pools for Cloud Build. | `bool` | `false` | no | -| essential\_contacts\_domains\_to\_allow | The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes | +| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | `bool` | `false` | no | +| essential\_contacts\_domains\_to\_allow | .The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes | | essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no | | folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | no | | gcp\_groups | Groups to grant specific roles in the Organization.
platform\_viewer: Google Workspace or Cloud Identity group that have the ability to view resource information across the Google Cloud organization.
security\_reviewer: Google Workspace or Cloud Identity group that members are part of the security team responsible for reviewing cloud security
network\_viewer: Google Workspace or Cloud Identity group that members are part of the networking team and review network configurations.
scc\_admin: Google Workspace or Cloud Identity group that can administer Security Command Center.
audit\_viewer: Google Workspace or Cloud Identity group that members are part of an audit team and view audit logs in the logging project.
global\_secrets\_admin: Google Workspace or Cloud Identity group that members are responsible for putting secrets into Secrets Management. |
object({
audit_viewer = optional(string, null)
security_reviewer = optional(string, null)
network_viewer = optional(string, null)
scc_admin = optional(string, null)
global_secrets_admin = optional(string, null)
kms_admin = optional(string, null)
})
| `{}` | no | +| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
})
}))
| `[]` | no | +| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
})
}))
| `[]` | no | | log\_export\_storage\_force\_destroy | (Optional) If set to true, delete all contents when destroying the resource; otherwise, destroying the resource will fail if contents are present. | `bool` | `false` | no | | log\_export\_storage\_location | The location of the storage bucket used to export logs. | `string` | `null` | no | | log\_export\_storage\_retention\_policy | Configuration of the bucket's data retention policy for how long objects in the bucket should be retained. |
object({
is_locked = bool
retention_period_days = number
})
| `null` | no | | log\_export\_storage\_versioning | (Optional) Toggles bucket versioning, ability to retain a non-current object version when the live object version gets replaced or deleted. | `bool` | `false` | no | +| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | +| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | project\_budget | Budget configuration for projects.
budget\_amount: The amount to use as the budget.
alert\_spent\_percents: A list of percentages of the budget to alert on when threshold is exceeded.
alert\_pubsub\_topic: The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`.
alert\_spend\_basis: The type of basis used to determine if spend has passed the threshold. Possible choices are `CURRENT_SPEND` or `FORECASTED_SPEND` (default). |
object({
net_hub_budget_amount = optional(number, 1000)
net_hub_alert_spent_percents = optional(list(number), [1.2])
net_hub_alert_pubsub_topic = optional(string, null)
net_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
shared_network_budget_amount = optional(number, 1000)
shared_network_alert_spent_percents = optional(list(number), [1.2])
shared_network_alert_pubsub_topic = optional(string, null)
shared_network_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
interconnect_budget_amount = optional(number, 1000)
interconnect_alert_spent_percents = optional(list(number), [1.2])
interconnect_alert_pubsub_topic = optional(string, null)
interconnect_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_secrets_budget_amount = optional(number, 1000)
org_secrets_alert_spent_percents = optional(list(number), [1.2])
org_secrets_alert_pubsub_topic = optional(string, null)
org_secrets_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_billing_export_budget_amount = optional(number, 1000)
org_billing_export_alert_spent_percents = optional(list(number), [1.2])
org_billing_export_alert_pubsub_topic = optional(string, null)
org_billing_export_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_audit_logs_budget_amount = optional(number, 1000)
org_audit_logs_alert_spent_percents = optional(list(number), [1.2])
org_audit_logs_alert_pubsub_topic = optional(string, null)
org_audit_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
common_kms_budget_amount = optional(number, 1000)
common_kms_alert_spent_percents = optional(list(number), [1.2])
common_kms_alert_pubsub_topic = optional(string, null)
common_kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
scc_notifications_budget_amount = optional(number, 1000)
scc_notifications_alert_spent_percents = optional(list(number), [1.2])
scc_notifications_alert_pubsub_topic = optional(string, null)
scc_notifications_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
})
| `{}` | no | | project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no | -| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | +| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps.. | `string` | n/a | yes | +| resources | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. | `list(string)` | `[]` | no | +| resources\_dry\_run | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set. | `list(string)` | `[]` | no | | scc\_notification\_filter | Filter used to create the Security Command Center Notification, you can see more details on how to create filters in https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications#create-filter | `string` | `"state = \"ACTIVE\""` | no | | scc\_notification\_name | Name of the Security Command Center Notification. It must be unique in the organization. Run `gcloud scc notifications describe --organization=org_id` to check if it already exists. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | From 85178d9ad0462c06cc9d6209c328f70b97d04100 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:30:40 -0300 Subject: [PATCH 009/114] add service control file --- 1-org/envs/shared/service_control.tf | 566 +++++++++++++++++++++++++++ 1 file changed, 566 insertions(+) create mode 100644 1-org/envs/shared/service_control.tf diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf new file mode 100644 index 000000000..1f0cc1764 --- /dev/null +++ b/1-org/envs/shared/service_control.tf @@ -0,0 +1,566 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************** + Shared VPC +*****************************************/ + +locals { + supported_restricted_service = [ + "serviceusage.googleapis.com", + "essentialcontacts.googleapis.com", + "accessapproval.googleapis.com", + "adsdatahub.googleapis.com", + "aiplatform.googleapis.com", + "alloydb.googleapis.com", + "alpha-documentai.googleapis.com", + "analyticshub.googleapis.com", + "apigee.googleapis.com", + "apigeeconnect.googleapis.com", + "artifactregistry.googleapis.com", + "assuredworkloads.googleapis.com", + "automl.googleapis.com", + "baremetalsolution.googleapis.com", + "batch.googleapis.com", + "bigquery.googleapis.com", + "bigquerydatapolicy.googleapis.com", + "bigquerydatatransfer.googleapis.com", + "bigquerymigration.googleapis.com", + "bigqueryreservation.googleapis.com", + "bigtable.googleapis.com", + "binaryauthorization.googleapis.com", + "cloud.googleapis.com", + "cloudasset.googleapis.com", + "cloudbuild.googleapis.com", + "clouddebugger.googleapis.com", + "clouddeploy.googleapis.com", + "clouderrorreporting.googleapis.com", + "cloudfunctions.googleapis.com", + "cloudkms.googleapis.com", + "cloudprofiler.googleapis.com", + "cloudresourcemanager.googleapis.com", + "cloudscheduler.googleapis.com", + "cloudsearch.googleapis.com", + "cloudtrace.googleapis.com", + "composer.googleapis.com", + "compute.googleapis.com", + "connectgateway.googleapis.com", + "contactcenterinsights.googleapis.com", + "container.googleapis.com", + "containeranalysis.googleapis.com", + "containerfilesystem.googleapis.com", + "containerregistry.googleapis.com", + "containerthreatdetection.googleapis.com", + "datacatalog.googleapis.com", + "dataflow.googleapis.com", + "datafusion.googleapis.com", + "datamigration.googleapis.com", + "dataplex.googleapis.com", + "dataproc.googleapis.com", + "datastream.googleapis.com", + "dialogflow.googleapis.com", + "dlp.googleapis.com", + "dns.googleapis.com", + "documentai.googleapis.com", + "domains.googleapis.com", + "eventarc.googleapis.com", + "file.googleapis.com", + "firebaseappcheck.googleapis.com", + "firebaserules.googleapis.com", + "firestore.googleapis.com", + "gameservices.googleapis.com", + "gkebackup.googleapis.com", + "gkeconnect.googleapis.com", + "gkehub.googleapis.com", + "healthcare.googleapis.com", + "iam.googleapis.com", + "iamcredentials.googleapis.com", + "iaptunnel.googleapis.com", + "ids.googleapis.com", + "integrations.googleapis.com", + "kmsinventory.googleapis.com", + "krmapihosting.googleapis.com", + "language.googleapis.com", + "lifesciences.googleapis.com", + "logging.googleapis.com", + "managedidentities.googleapis.com", + "memcache.googleapis.com", + "meshca.googleapis.com", + "meshconfig.googleapis.com", + "metastore.googleapis.com", + "ml.googleapis.com", + "monitoring.googleapis.com", + "networkconnectivity.googleapis.com", + "networkmanagement.googleapis.com", + "networksecurity.googleapis.com", + "networkservices.googleapis.com", + "notebooks.googleapis.com", + "opsconfigmonitoring.googleapis.com", + "orgpolicy.googleapis.com", + "osconfig.googleapis.com", + "oslogin.googleapis.com", + "privateca.googleapis.com", + "pubsub.googleapis.com", + "pubsublite.googleapis.com", + "recaptchaenterprise.googleapis.com", + "recommender.googleapis.com", + "redis.googleapis.com", + "retail.googleapis.com", + "run.googleapis.com", + "secretmanager.googleapis.com", + "servicecontrol.googleapis.com", + "servicedirectory.googleapis.com", + "spanner.googleapis.com", + "speakerid.googleapis.com", + "speech.googleapis.com", + "sqladmin.googleapis.com", + "storage.googleapis.com", + "storagetransfer.googleapis.com", + "sts.googleapis.com", + "texttospeech.googleapis.com", + "timeseriesinsights.googleapis.com", + "tpu.googleapis.com", + "trafficdirector.googleapis.com", + "transcoder.googleapis.com", + "translate.googleapis.com", + "videointelligence.googleapis.com", + "vision.googleapis.com", + "visionai.googleapis.com", + "vmmigration.googleapis.com", + "vpcaccess.googleapis.com", + "webrisk.googleapis.com", + "workflows.googleapis.com", + "workstations.googleapis.com", + ] + + restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service + restricted_services_dry_run = length(var.custom_restricted_services_dry_run) != 0 ? var.custom_restricted_services : local.supported_restricted_service + access_level_name = module.service_control.access_level_name + access_level_dry_run_name = module.service_control.access_level_name_dry_run + + shared_vpc_projects_numbers = [ + for v in values({ + for k, m in module.environment_network : + k => m.shared_vpc_project_number + }) : tostring(v) + ] + + projects = distinct(concat([ + local.seed_project_number, + module.org_audit_logs.project_number, + module.org_billing_export.project_number, + module.common_kms.project_number, + module.org_secrets.project_number, + module.interconnect.project_number, + module.scc_notifications.project_number, + ], local.shared_vpc_projects_numbers + )) + + project_keys = [ + "prj-org-seed", + "prj-org-audit", + "prj-org-billing", + "prj-org-kms", + "prj-org-secrets", + "prj-org-interconnect", + "prj-org-scc", + "prj-net-p-svpc", + "prj-net-d-svpc", + "prj-net-n-svpc", + ] + + projects_map = zipmap( + local.project_keys, + [for p in local.projects : "${p}"] + ) + + required_egress_rules_dry_run = [ + { + from = { + identities = [ + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.seed_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + operations = { + "cloudbuild.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:${local.organization_service_account}", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { + "cloudasset.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + + required_ingress_rules_dry_run = [ + { + from = { + identities = [ + "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.org_billing_export.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", + "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.org_audit_logs.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + + "pubsub.googleapis.com" = { + methods = ["*"] + } + + "storage.googleapis.com" = { + methods = ["*"] + } + + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "iam.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "cloudbuild.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + + required_ingress_rules = [ + { + from = { + identities = [ + "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.org_billing_export.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", + "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.org_audit_logs.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + + "pubsub.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "iam.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "cloudbuild.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + + required_egress_rules = [ + { + from = { + identities = [ + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.seed_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + operations = { + "cloudbuild.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:${local.organization_service_account}", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { + "cloudasset.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] +} + +module "service_control" { + source = "../../modules/service_control" + + access_context_manager_policy_id = var.access_context_manager_policy_id + restricted_services = local.restricted_services + restricted_services_dry_run = local.restricted_services_dry_run + members = distinct(concat([ + "serviceAccount:${local.networks_service_account}", + "serviceAccount:${local.projects_service_account}", + "serviceAccount:${local.organization_service_account}", + "serviceAccount:${local.environment_service_account}", + ], var.perimeter_additional_members)) + resources = concat(values(local.projects_map), var.resources) + resource_keys = local.project_keys + members_dry_run = distinct(concat([ + "serviceAccount:${local.networks_service_account}", + "serviceAccount:${local.projects_service_account}", + "serviceAccount:${local.organization_service_account}", + "serviceAccount:${local.environment_service_account}", + ], var.perimeter_additional_members)) + resources_dry_run = concat(values(local.projects_map), var.resources_dry_run) + resource_keys_dry_run = local.project_keys + ingress_policies = var.enforce_vpcsc ? distinct(concat(var.ingress_policies, local.required_ingress_rules)) : tolist([]) + ingress_policies_dry_run = !var.enforce_vpcsc ? distinct(concat(var.ingress_policies_dry_run, local.required_ingress_rules_dry_run)) : tolist([]) + egress_policies = distinct(concat(var.egress_policies, local.required_egress_rules)) + egress_policies_dry_run = distinct(concat(var.egress_policies_dry_run, local.required_egress_rules_dry_run)) + enforce_vpcsc = var.enforce_vpcsc + + depends_on = [ + time_sleep.wait_projects + ] +} From 97d9f6bbef583bf7386b97185cae58c3c643c9c2 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:32:22 -0300 Subject: [PATCH 010/114] add depends on in projects.tf --- 1-org/envs/shared/projects.tf | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/1-org/envs/shared/projects.tf b/1-org/envs/shared/projects.tf index 5798fa6b1..dd7e4095c 100644 --- a/1-org/envs/shared/projects.tf +++ b/1-org/envs/shared/projects.tf @@ -90,6 +90,7 @@ module "org_billing_export" { env_code = "c" vpc = "none" } + budget_alert_pubsub_topic = var.project_budget.org_billing_export_alert_pubsub_topic budget_alert_spent_percents = var.project_budget.org_billing_export_alert_spent_percents budget_amount = var.project_budget.org_billing_export_budget_amount @@ -149,6 +150,7 @@ module "org_secrets" { deletion_policy = var.project_deletion_policy activate_apis = ["logging.googleapis.com", "secretmanager.googleapis.com", "billingbudgets.googleapis.com"] + labels = { environment = "common" application_name = "org-secrets" @@ -193,6 +195,7 @@ module "interconnect" { env_code = "net" vpc = "none" } + budget_alert_pubsub_topic = var.project_budget.interconnect_alert_pubsub_topic budget_alert_spent_percents = var.project_budget.interconnect_alert_spent_percents budget_amount = var.project_budget.interconnect_budget_amount @@ -227,6 +230,7 @@ module "scc_notifications" { env_code = "c" vpc = "none" } + budget_alert_pubsub_topic = var.project_budget.scc_notifications_alert_pubsub_topic budget_alert_spent_percents = var.project_budget.scc_notifications_alert_spent_percents budget_amount = var.project_budget.scc_notifications_budget_amount @@ -270,6 +274,7 @@ module "network_hub" { env_code = "net" vpc = "svpc" } + budget_alert_pubsub_topic = var.project_budget.net_hub_alert_pubsub_topic budget_alert_spent_percents = var.project_budget.net_hub_alert_spent_percents budget_amount = var.project_budget.net_hub_budget_amount @@ -313,3 +318,18 @@ resource "google_project_iam_member" "network_sa" { role = each.key member = "serviceAccount:${local.networks_step_terraform_service_account_email}" } + +resource "time_sleep" "wait_projects" { + create_duration = "30s" + + depends_on = [ + module.org_audit_logs, + module.org_billing_export, + module.common_kms, + module.org_secrets, + module.interconnect, + module.scc_notifications, + module.network_hub, + module.environment_network + ] +} From e0186cb52f4056f6571caa833308f70759b4417a Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:34:21 -0300 Subject: [PATCH 011/114] add SA builder cloud function --- 1-org/envs/shared/outputs.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/1-org/envs/shared/outputs.tf b/1-org/envs/shared/outputs.tf index df9e55da2..87f91e8b2 100644 --- a/1-org/envs/shared/outputs.tf +++ b/1-org/envs/shared/outputs.tf @@ -148,3 +148,8 @@ output "cai_monitoring_topic" { value = try(module.cai_monitoring[0].topic_name, null) description = "CAI Monitoring Cloud Function Pub/Sub Topic name." } + +output "build_service_account" { + description = "Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container." + value = google_service_account.cai_monitoring_builder[0].email +} From c100a00a7728da3e02abd19d48017df87811f2f4 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:34:45 -0300 Subject: [PATCH 012/114] add access context manager in org_policy.tf --- 1-org/envs/shared/org_policy.tf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/1-org/envs/shared/org_policy.tf b/1-org/envs/shared/org_policy.tf index 08ea8acda..2aa44c878 100644 --- a/1-org/envs/shared/org_policy.tf +++ b/1-org/envs/shared/org_policy.tf @@ -41,7 +41,8 @@ locals { "storage.publicAccessPrevention" ]) - private_pools = [local.cloud_build_private_worker_pool_id] + private_pools = [local.cloud_build_private_worker_pool_id] + access_context_manager_policy_id = var.create_access_context_manager_access_policy ? google_access_context_manager_access_policy.access_policy[0].id : var.access_context_manager_policy_id } module "organization_policies_type_boolean" { From 55ad04a31198453ef329177da15f4b71febce230 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:36:58 -0300 Subject: [PATCH 013/114] add access context manager policy id variable --- 1-org/envs/shared/terraform.example.tfvars | 2 ++ 1 file changed, 2 insertions(+) diff --git a/1-org/envs/shared/terraform.example.tfvars b/1-org/envs/shared/terraform.example.tfvars index 7a2e3a69f..cd15c086c 100644 --- a/1-org/envs/shared/terraform.example.tfvars +++ b/1-org/envs/shared/terraform.example.tfvars @@ -43,3 +43,5 @@ billing_export_dataset_location = "US" // unique organization-wide it will add a random suffix at each tag key //create_unique_tag_key = true + +access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID \ No newline at end of file From 7887d10fd665068732589636a4666d3de53c127d Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:37:58 -0300 Subject: [PATCH 014/114] updt README --- 1-org/envs/shared/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 90e5a1dbc..65dcc71e7 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -43,6 +43,7 @@ | Name | Description | |------|-------------| | billing\_sink\_names | The name of the sinks under billing account level. | +| build\_service\_account | Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container. | | cai\_monitoring\_artifact\_registry | CAI Monitoring Cloud Function Artifact Registry name. | | cai\_monitoring\_asset\_feed | CAI Monitoring Cloud Function Organization Asset Feed name. | | cai\_monitoring\_bucket | CAI Monitoring Cloud Function Source Bucket name. | From 948a08f892f48e53b21adce9e66aab166a5cfe16 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:40:03 -0300 Subject: [PATCH 015/114] add log sinks identities outputs --- 1-org/modules/centralized-logging/outputs.tf | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/1-org/modules/centralized-logging/outputs.tf b/1-org/modules/centralized-logging/outputs.tf index 8219994f5..5c9fd6325 100644 --- a/1-org/modules/centralized-logging/outputs.tf +++ b/1-org/modules/centralized-logging/outputs.tf @@ -41,3 +41,24 @@ output "billing_sink_names" { key => "${coalesce(options.logging_sink_name, local.logging_sink_name_map[key])}-billing-${random_string.suffix.result}" } } + +output "log_export_billing" { + description = "The service account that logging uses to write log entries to the destination." + value = { + for k, m in module.log_export_billing : + k => m.writer_identity + } +} + +output "log_export" { + description = "The service account that logging uses to write log entries to the destination." + value = { + for k, m in module.log_export : + k => m.writer_identity + } +} + +output "internal_project_log_export" { + description = "The service account that logging uses to write log entries to the destination." + value = module.internal_project_log_export[0].writer_identity +} From f4b0a95bcc098bbb773b114f3f92d8b0bba3fec1 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:43:35 -0300 Subject: [PATCH 016/114] upd README --- 1-org/modules/centralized-logging/README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/1-org/modules/centralized-logging/README.md b/1-org/modules/centralized-logging/README.md index 158a02f13..bd6c0be61 100644 --- a/1-org/modules/centralized-logging/README.md +++ b/1-org/modules/centralized-logging/README.md @@ -74,6 +74,9 @@ module "logging_logbucket" { | Name | Description | |------|-------------| | billing\_sink\_names | Map of log sink names with billing suffix | +| internal\_project\_log\_export | The service account that logging uses to write log entries to the destination. | +| log\_export | The service account that logging uses to write log entries to the destination. | +| log\_export\_billing | The service account that logging uses to write log entries to the destination. | | project\_linked\_dataset\_name | The resource name of the Log Bucket linked BigQuery dataset for the project destination. | | project\_logbucket\_name | The resource name for the Log Bucket created for the project destination. | | pubsub\_destination\_name | The resource name for the destination Pub/Sub. | From 3ce8b8d4aeb5ac110cdf657479587430dacbdce2 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:53:09 -0300 Subject: [PATCH 017/114] upd README with new instructions --- 1-org/README.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/1-org/README.md b/1-org/README.md index 5bce9c13b..1c9ac202b 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -55,7 +55,8 @@ For an overview of the architecture and the parts, see the ## Purpose -The purpose of this step is to set up top-level shared folders, networking projects, organization-level logging, and baseline security settings through organizational policies. +- Set up top-level shared folders, networking projects, organization-level logging, and baseline security settings through organizational policies. +- Set up VPC Service Controls. ## Prerequisites @@ -155,6 +156,12 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" ``` +1. Update `envs/shared/terraform.tfvars` file with the `access_context_manager_policy_id`. + + ```bash + sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./envs/shared/terraform.tfvars + ``` + 1. Update the `envs/shared/terraform.tfvars` file with values from your environment and 0-bootstrap step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash @@ -166,6 +173,14 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f if [ ! -z "${ACCESS_CONTEXT_MANAGER_ID}" ]; then sed -i'' -e "s=//create_access_context_manager_access_policy=create_access_context_manager_access_policy=" ./envs/shared/terraform.tfvars; fi ``` +1. Run `terraform init` in `/envs/shared` to generate the outputs used in other steps. + + ```bash + cd envs/shared + terraform init + cd ../.. + ``` + 1. Commit changes. ```bash @@ -249,6 +264,12 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" ``` +1. Update `envs/shared/terraform.tfvars` file with the `access_context_manager_policy_id`. + + ```bash + sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./envs/shared/terraform.tfvars + ``` + 1. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash @@ -310,3 +331,11 @@ Before executing the next stages, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` + +### (Optional) Enforce VPC Service Controls + +Because enabling VPC Service Controls can be a disruptive process, this repo configures VPC Service Controls perimeters in dry run mode by default. This configuration will service traffic that crosses the security perimeter (API requests that originate from inside your perimeter communicating with external resources, or API requests from external resources communicating with resources inside your perimeter) but still allow service traffic normally. + +When you are ready to enforce VPC Service Controls, we recommend that you review the guidance at [Best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable). After you have added the necessary exceptions and are confident that VPC Service Controls will not disrupt your intended operations, set the variable `enforce_vpcsc` under the module `service_control` to `true` and re-apply this stage. Then re-apply the 2-environments and 4-projects stage, which will inherit the new setting and include those projects inside the enforced perimeter. + +When you need to make changes to an existing enforced perimeter, you can test safely by modifying the configuration of the [dry run perimeter](https://cloud.google.com/vpc-service-controls/docs/dry-run-mode). This will log traffic denied by the dry run perimeter without impacting whether the enforced perimeter allows or denies traffic. From 41446827ac69d248be409c8ed38387b82cce7986 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:55:35 -0300 Subject: [PATCH 018/114] add enforce_vpcsc in remote.tf --- 2-environments/modules/env_baseline/remote.tf | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/2-environments/modules/env_baseline/remote.tf b/2-environments/modules/env_baseline/remote.tf index 521bab9cc..539eb90d4 100644 --- a/2-environments/modules/env_baseline/remote.tf +++ b/2-environments/modules/env_baseline/remote.tf @@ -15,13 +15,16 @@ */ locals { - org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id - parent = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id - billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account - project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix - folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix - tags = data.terraform_remote_state.org.outputs.tags - required_groups = data.terraform_remote_state.bootstrap.outputs.required_groups + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + parent = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix + tags = data.terraform_remote_state.org.outputs.tags + required_groups = data.terraform_remote_state.bootstrap.outputs.required_groups + enforce_vpcsc = data.terraform_remote_state.org.outputs.enforce_vpcsc + perimeter_name = data.terraform_remote_state.org.outputs.service_perimeter_name + access_context_manager_policy_id = data.terraform_remote_state.org.outputs.access_context_manager_policy_id } data "terraform_remote_state" "bootstrap" { From ff20ec1c2db95801105ddf225daca46d7735af25 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:56:25 -0300 Subject: [PATCH 019/114] add kms prjs in vpc-sc --- 2-environments/modules/env_baseline/kms.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/2-environments/modules/env_baseline/kms.tf b/2-environments/modules/env_baseline/kms.tf index 1514991c1..2f7a371ed 100644 --- a/2-environments/modules/env_baseline/kms.tf +++ b/2-environments/modules/env_baseline/kms.tf @@ -35,6 +35,10 @@ module "env_kms" { activate_apis = ["logging.googleapis.com", "cloudkms.googleapis.com", "billingbudgets.googleapis.com"] deletion_policy = var.project_deletion_policy + vpc_service_control_attach_enabled = local.enforce_vpcsc ? "true" : "false" + vpc_service_control_attach_dry_run = !local.enforce_vpcsc ? "true" : "false" + vpc_service_control_perimeter_name = "accessPolicies/${local.access_context_manager_policy_id}/servicePerimeters/${local.perimeter_name}" + labels = { environment = var.env application_name = "env-kms" @@ -45,6 +49,7 @@ module "env_kms" { env_code = var.environment_code vpc = "none" } + budget_alert_pubsub_topic = var.project_budget.kms_alert_pubsub_topic budget_alert_spent_percents = var.project_budget.kms_alert_spent_percents budget_amount = var.project_budget.kms_budget_amount From c6f1ed588b19490311e4abba5da8164f67a14d6c Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 15:57:49 -0300 Subject: [PATCH 020/114] add secrets prjs in vpc-sc --- 2-environments/modules/env_baseline/secrets.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/2-environments/modules/env_baseline/secrets.tf b/2-environments/modules/env_baseline/secrets.tf index 7b04f93ee..2e74a693c 100644 --- a/2-environments/modules/env_baseline/secrets.tf +++ b/2-environments/modules/env_baseline/secrets.tf @@ -35,6 +35,10 @@ module "env_secrets" { activate_apis = ["logging.googleapis.com", "secretmanager.googleapis.com"] deletion_policy = var.project_deletion_policy + vpc_service_control_attach_enabled = local.enforce_vpcsc ? "true" : "false" + vpc_service_control_attach_dry_run = !local.enforce_vpcsc ? "true" : "false" + vpc_service_control_perimeter_name = "accessPolicies/${local.access_context_manager_policy_id}/servicePerimeters/${local.perimeter_name}" + labels = { environment = var.env application_name = "env-secrets" @@ -45,6 +49,7 @@ module "env_secrets" { env_code = var.environment_code vpc = "none" } + budget_alert_pubsub_topic = var.project_budget.secret_alert_pubsub_topic budget_alert_spent_percents = var.project_budget.secret_alert_spent_percents budget_amount = var.project_budget.secret_budget_amount From 75e9207123b818cde200c622712a378ddfe06d06 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 16:12:08 -0300 Subject: [PATCH 021/114] rm all related to vpc-sc --- 3-networks-svpc/common.auto.example.tfvars | 5 - 3-networks-svpc/envs/development/README.md | 10 - 3-networks-svpc/envs/development/main.tf | 6 - 3-networks-svpc/envs/development/outputs.tf | 20 -- 3-networks-svpc/envs/development/variables.tf | 48 ----- 3-networks-svpc/envs/nonproduction/README.md | 10 - 3-networks-svpc/envs/nonproduction/main.tf | 34 ++-- 3-networks-svpc/envs/nonproduction/outputs.tf | 20 -- .../envs/nonproduction/variables.tf | 48 ----- 3-networks-svpc/envs/production/README.md | 10 - 3-networks-svpc/envs/production/main.tf | 36 ++-- 3-networks-svpc/envs/production/outputs.tf | 20 -- 3-networks-svpc/envs/production/variables.tf | 48 ----- 3-networks-svpc/modules/base_env/README.md | 12 -- 3-networks-svpc/modules/base_env/main.tf | 182 +----------------- 3-networks-svpc/modules/base_env/outputs.tf | 20 -- 3-networks-svpc/modules/base_env/variables.tf | 61 ------ 3-networks-svpc/modules/shared_vpc/README.md | 13 -- 3-networks-svpc/modules/shared_vpc/outputs.tf | 21 -- .../modules/shared_vpc/service_control.tf | 100 ---------- .../modules/shared_vpc/variables.tf | 63 ------ 21 files changed, 36 insertions(+), 751 deletions(-) delete mode 100644 3-networks-svpc/modules/shared_vpc/service_control.tf diff --git a/3-networks-svpc/common.auto.example.tfvars b/3-networks-svpc/common.auto.example.tfvars index 441314aae..c39ec48dd 100644 --- a/3-networks-svpc/common.auto.example.tfvars +++ b/3-networks-svpc/common.auto.example.tfvars @@ -17,9 +17,4 @@ // The DNS name of peering managed zone. Must end with a period. domain = "example.com." -// Update the following line and add you email in the perimeter_additional_members list. -// You must be in this list to be able to view/access resources in the project protected by the VPC service controls. - -perimeter_additional_members = ["user:YOUR-USER-EMAIL@example.com"] - remote_state_bucket = "REMOTE_STATE_BUCKET" diff --git a/3-networks-svpc/envs/development/README.md b/3-networks-svpc/envs/development/README.md index 92774e3cb..d69c834f0 100644 --- a/3-networks-svpc/envs/development/README.md +++ b/3-networks-svpc/envs/development/README.md @@ -17,12 +17,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -31,12 +25,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| | access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/envs/development/main.tf b/3-networks-svpc/envs/development/main.tf index d948f1043..6264d8c16 100644 --- a/3-networks-svpc/envs/development/main.tf +++ b/3-networks-svpc/envs/development/main.tf @@ -49,15 +49,9 @@ module "base_env" { env = local.env environment_code = local.environment_code access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run enable_partner_interconnect = false private_service_cidr = local.private_service_cidr subnet_primary_ranges = local.subnet_primary_ranges diff --git a/3-networks-svpc/envs/development/outputs.tf b/3-networks-svpc/envs/development/outputs.tf index c104444fd..7abbe4f96 100644 --- a/3-networks-svpc/envs/development/outputs.tf +++ b/3-networks-svpc/envs/development/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-svpc/envs/development/variables.tf b/3-networks-svpc/envs/development/variables.tf index 02448e5a9..beab69a7b 100644 --- a/3-networks-svpc/envs/development/variables.tf +++ b/3-networks-svpc/envs/development/variables.tf @@ -29,54 +29,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/envs/nonproduction/README.md b/3-networks-svpc/envs/nonproduction/README.md index 33377827e..1d147e226 100644 --- a/3-networks-svpc/envs/nonproduction/README.md +++ b/3-networks-svpc/envs/nonproduction/README.md @@ -17,12 +17,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -31,12 +25,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| | access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/envs/nonproduction/main.tf b/3-networks-svpc/envs/nonproduction/main.tf index 2686cf532..81137c53f 100644 --- a/3-networks-svpc/envs/nonproduction/main.tf +++ b/3-networks-svpc/envs/nonproduction/main.tf @@ -44,24 +44,18 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_primary_ranges = local.subnet_primary_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.7" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + access_context_manager_policy_id = var.access_context_manager_policy_id + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_primary_ranges = local.subnet_primary_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.7" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-svpc/envs/nonproduction/outputs.tf b/3-networks-svpc/envs/nonproduction/outputs.tf index c104444fd..7abbe4f96 100644 --- a/3-networks-svpc/envs/nonproduction/outputs.tf +++ b/3-networks-svpc/envs/nonproduction/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-svpc/envs/nonproduction/variables.tf b/3-networks-svpc/envs/nonproduction/variables.tf index 02448e5a9..beab69a7b 100644 --- a/3-networks-svpc/envs/nonproduction/variables.tf +++ b/3-networks-svpc/envs/nonproduction/variables.tf @@ -29,54 +29,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/envs/production/README.md b/3-networks-svpc/envs/production/README.md index 01a596fbd..7f0b43dc9 100644 --- a/3-networks-svpc/envs/production/README.md +++ b/3-networks-svpc/envs/production/README.md @@ -17,12 +17,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | `[]` | no | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -32,12 +26,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| | access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/envs/production/main.tf b/3-networks-svpc/envs/production/main.tf index 07e043eb1..86d273dee 100644 --- a/3-networks-svpc/envs/production/main.tf +++ b/3-networks-svpc/envs/production/main.tf @@ -44,25 +44,19 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.8" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name - target_name_server_addresses = var.target_name_server_addresses + env = local.env + environment_code = local.environment_code + access_context_manager_policy_id = var.access_context_manager_policy_id + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.8" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name + target_name_server_addresses = var.target_name_server_addresses } diff --git a/3-networks-svpc/envs/production/outputs.tf b/3-networks-svpc/envs/production/outputs.tf index c104444fd..7abbe4f96 100644 --- a/3-networks-svpc/envs/production/outputs.tf +++ b/3-networks-svpc/envs/production/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-svpc/envs/production/variables.tf b/3-networks-svpc/envs/production/variables.tf index 588a9e69d..4746763fd 100644 --- a/3-networks-svpc/envs/production/variables.tf +++ b/3-networks-svpc/envs/production/variables.tf @@ -35,54 +35,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/modules/base_env/README.md b/3-networks-svpc/modules/base_env/README.md index 928e11794..9b6705e02 100644 --- a/3-networks-svpc/modules/base_env/README.md +++ b/3-networks-svpc/modules/base_env/README.md @@ -4,21 +4,13 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | -| custom\_restricted\_services | List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | -| custom\_restricted\_services\_dry\_run | List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_dedicated\_interconnect | Enable Dedicated Interconnect in the environment. | `bool` | `false` | no | | enable\_partner\_interconnect | Enable Partner Interconnect in the environment. | `bool` | `false` | no | | env | The environment to prepare (ex. development) | `string` | n/a | yes | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization (ex. d). | `string` | n/a | yes | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Shared Vpc. | `string` | n/a | yes | | private\_service\_connect\_ip | The base subnet internal IP to be used as the private service connect endpoint in the Shared VPC | `string` | n/a | yes | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | @@ -33,12 +25,8 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-svpc/modules/base_env/main.tf b/3-networks-svpc/modules/base_env/main.tf index ba632c9db..5d8c1ad5c 100644 --- a/3-networks-svpc/modules/base_env/main.tf +++ b/3-networks-svpc/modules/base_env/main.tf @@ -15,152 +15,7 @@ */ locals { - dedicated_interconnect_egress_policy = var.enable_dedicated_interconnect ? [ - { - "from" = { - "identity_type" = "" - "identities" = ["serviceAccount:${local.networks_service_account}"] - }, - "to" = { - "resources" = ["projects/${local.interconnect_project_number}"] - "operations" = { - "compute.googleapis.com" = { - "methods" = ["*"] - } - } - } - }, - ] : [] - bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" - - supported_restricted_service = [ - "accessapproval.googleapis.com", - "adsdatahub.googleapis.com", - "aiplatform.googleapis.com", - "alloydb.googleapis.com", - "alpha-documentai.googleapis.com", - "analyticshub.googleapis.com", - "apigee.googleapis.com", - "apigeeconnect.googleapis.com", - "artifactregistry.googleapis.com", - "assuredworkloads.googleapis.com", - "automl.googleapis.com", - "baremetalsolution.googleapis.com", - "batch.googleapis.com", - "bigquery.googleapis.com", - "bigquerydatapolicy.googleapis.com", - "bigquerydatatransfer.googleapis.com", - "bigquerymigration.googleapis.com", - "bigqueryreservation.googleapis.com", - "bigtable.googleapis.com", - "binaryauthorization.googleapis.com", - "cloud.googleapis.com", - "cloudasset.googleapis.com", - "cloudbuild.googleapis.com", - "clouddebugger.googleapis.com", - "clouddeploy.googleapis.com", - "clouderrorreporting.googleapis.com", - "cloudfunctions.googleapis.com", - "cloudkms.googleapis.com", - "cloudprofiler.googleapis.com", - "cloudresourcemanager.googleapis.com", - "cloudscheduler.googleapis.com", - "cloudsearch.googleapis.com", - "cloudtrace.googleapis.com", - "composer.googleapis.com", - "compute.googleapis.com", - "connectgateway.googleapis.com", - "contactcenterinsights.googleapis.com", - "container.googleapis.com", - "containeranalysis.googleapis.com", - "containerfilesystem.googleapis.com", - "containerregistry.googleapis.com", - "containerthreatdetection.googleapis.com", - "datacatalog.googleapis.com", - "dataflow.googleapis.com", - "datafusion.googleapis.com", - "datamigration.googleapis.com", - "dataplex.googleapis.com", - "dataproc.googleapis.com", - "datastream.googleapis.com", - "dialogflow.googleapis.com", - "dlp.googleapis.com", - "dns.googleapis.com", - "documentai.googleapis.com", - "domains.googleapis.com", - "eventarc.googleapis.com", - "file.googleapis.com", - "firebaseappcheck.googleapis.com", - "firebaserules.googleapis.com", - "firestore.googleapis.com", - "gameservices.googleapis.com", - "gkebackup.googleapis.com", - "gkeconnect.googleapis.com", - "gkehub.googleapis.com", - "healthcare.googleapis.com", - "iam.googleapis.com", - "iamcredentials.googleapis.com", - "iaptunnel.googleapis.com", - "ids.googleapis.com", - "integrations.googleapis.com", - "kmsinventory.googleapis.com", - "krmapihosting.googleapis.com", - "language.googleapis.com", - "lifesciences.googleapis.com", - "logging.googleapis.com", - "managedidentities.googleapis.com", - "memcache.googleapis.com", - "meshca.googleapis.com", - "meshconfig.googleapis.com", - "metastore.googleapis.com", - "ml.googleapis.com", - "monitoring.googleapis.com", - "networkconnectivity.googleapis.com", - "networkmanagement.googleapis.com", - "networksecurity.googleapis.com", - "networkservices.googleapis.com", - "notebooks.googleapis.com", - "opsconfigmonitoring.googleapis.com", - "orgpolicy.googleapis.com", - "osconfig.googleapis.com", - "oslogin.googleapis.com", - "privateca.googleapis.com", - "pubsub.googleapis.com", - "pubsublite.googleapis.com", - "recaptchaenterprise.googleapis.com", - "recommender.googleapis.com", - "redis.googleapis.com", - "retail.googleapis.com", - "run.googleapis.com", - "secretmanager.googleapis.com", - "servicecontrol.googleapis.com", - "servicedirectory.googleapis.com", - "spanner.googleapis.com", - "speakerid.googleapis.com", - "speech.googleapis.com", - "sqladmin.googleapis.com", - "storage.googleapis.com", - "storagetransfer.googleapis.com", - "sts.googleapis.com", - "texttospeech.googleapis.com", - "timeseriesinsights.googleapis.com", - "tpu.googleapis.com", - "trafficdirector.googleapis.com", - "transcoder.googleapis.com", - "translate.googleapis.com", - "videointelligence.googleapis.com", - "vision.googleapis.com", - "visionai.googleapis.com", - "vmmigration.googleapis.com", - "vpcaccess.googleapis.com", - "webrisk.googleapis.com", - "workflows.googleapis.com", - "workstations.googleapis.com", - ] - - restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service - restricted_services_dry_run = length(var.custom_restricted_services_dry_run) != 0 ? var.custom_restricted_services : local.supported_restricted_service } /****************************************** @@ -174,35 +29,13 @@ module "shared_vpc" { dns_project_id = local.dns_project_id environment_code = var.environment_code access_context_manager_policy_id = var.access_context_manager_policy_id - restricted_services = local.restricted_services - restricted_services_dry_run = local.restricted_services_dry_run - members = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - members_dry_run = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - private_service_cidr = var.private_service_cidr - private_service_connect_ip = var.private_service_connect_ip - bgp_asn_subnet = local.bgp_asn_number - default_region1 = var.default_region1 - default_region2 = var.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = distinct(concat( - local.dedicated_interconnect_egress_policy, - var.egress_policies - )) - egress_policies_dry_run = distinct(concat( - local.dedicated_interconnect_egress_policy, - var.egress_policies_dry_run - )) - target_name_server_addresses = var.target_name_server_addresses + private_service_cidr = var.private_service_cidr + private_service_connect_ip = var.private_service_connect_ip + bgp_asn_subnet = local.bgp_asn_number + default_region1 = var.default_region1 + default_region2 = var.default_region2 + domain = var.domain + target_name_server_addresses = var.target_name_server_addresses @@ -256,4 +89,3 @@ module "shared_vpc" { "sb-${var.environment_code}-svpc-${var.default_region1}" = var.subnet_secondary_ranges[var.default_region1] } } - diff --git a/3-networks-svpc/modules/base_env/outputs.tf b/3-networks-svpc/modules/base_env/outputs.tf index c55a4771c..49b75b865 100644 --- a/3-networks-svpc/modules/base_env/outputs.tf +++ b/3-networks-svpc/modules/base_env/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.shared_vpc.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.shared_vpc.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = module.shared_vpc.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.shared_vpc.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.shared_vpc.service_perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} diff --git a/3-networks-svpc/modules/base_env/variables.tf b/3-networks-svpc/modules/base_env/variables.tf index 378bf1788..0637807a6 100644 --- a/3-networks-svpc/modules/base_env/variables.tf +++ b/3-networks-svpc/modules/base_env/variables.tf @@ -110,67 +110,6 @@ EOT default = {} } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - - -variable "custom_restricted_services" { - description = "List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - -variable "custom_restricted_services_dry_run" { - description = "List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-svpc/modules/shared_vpc/README.md b/3-networks-svpc/modules/shared_vpc/README.md index cfec1feae..66fb953eb 100644 --- a/3-networks-svpc/modules/shared_vpc/README.md +++ b/3-networks-svpc/modules/shared_vpc/README.md @@ -11,16 +11,9 @@ | dns\_enable\_logging | Toggle DNS logging for VPC DNS. | `bool` | `true` | no | | dns\_project\_id | Project ID for DNS Restricted Shared. | `string` | `""` | no | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_all\_vpc\_internal\_traffic | Enable firewall policy rule to allow internal traffic (ingress and egress). | `bool` | `false` | no | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | `bool` | `false` | no | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization. | `string` | n/a | yes | | firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls. | `bool` | `true` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| members | An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | -| members\_dry\_run | An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | | nat\_bgp\_asn | BGP ASN for NAT cloud routes. If NAT is enabled this variable value must be a value in ranges [64512..65534] or [4200000000..4294967294]. | `number` | `64512` | no | | nat\_enabled | Toggle creation of NAT cloud router. | `bool` | `false` | no | | nat\_num\_addresses\_region1 | Number of external IPs to reserve for region 1 Cloud NAT. | `number` | `2` | no | @@ -29,8 +22,6 @@ | private\_service\_connect\_ip | Internal IP to be used as the private service connect endpoint. | `string` | n/a | yes | | project\_id | Project ID for Shared VPC. | `string` | n/a | yes | | project\_number | Project number for Shared VPC. | `number` | n/a | yes | -| restricted\_services | List of services to restrict in an enforced perimeter. | `list(string)` | n/a | yes | -| restricted\_services\_dry\_run | List of services to restrict in a dry-run perimeter. | `list(string)` | n/a | yes | | secondary\_ranges | Secondary ranges that will be used in some of the subnets | `map(list(object({ range_name = string, ip_cidr_range = string })))` | `{}` | no | | subnets | The list of subnets being created |
list(object({
subnet_name = string
subnet_ip = string
subnet_region = string
subnet_private_access = optional(string, "false")
subnet_private_ipv6_access = optional(string)
subnet_flow_logs = optional(string, "false")
subnet_flow_logs_interval = optional(string, "INTERVAL_5_SEC")
subnet_flow_logs_sampling = optional(string, "0.5")
subnet_flow_logs_metadata = optional(string, "INCLUDE_ALL_METADATA")
subnet_flow_logs_filter = optional(string, "true")
subnet_flow_logs_metadata_fields = optional(list(string), [])
description = optional(string)
purpose = optional(string)
role = optional(string)
stack_type = optional(string)
ipv6_access_type = optional(string)
}))
| `[]` | no | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | n/a | yes | @@ -40,16 +31,12 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | region1\_router1 | Router 1 for Region 1 | | region1\_router2 | Router 2 for Region 1 | | region2\_router1 | Router 1 for Region 2 | | region2\_router2 | Router 2 for Region 2 | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | | subnets\_regions | The region where the subnets will be created | diff --git a/3-networks-svpc/modules/shared_vpc/outputs.tf b/3-networks-svpc/modules/shared_vpc/outputs.tf index 748ec4ca3..fd1622a7f 100644 --- a/3-networks-svpc/modules/shared_vpc/outputs.tf +++ b/3-networks-svpc/modules/shared_vpc/outputs.tf @@ -68,24 +68,3 @@ output "region2_router2" { value = module.region2_router2 description = "Router 2 for Region 2" } - -output "access_level_name" { - value = local.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = local.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = var.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = local.perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} - diff --git a/3-networks-svpc/modules/shared_vpc/service_control.tf b/3-networks-svpc/modules/shared_vpc/service_control.tf deleted file mode 100644 index 16c8905fd..000000000 --- a/3-networks-svpc/modules/shared_vpc/service_control.tf +++ /dev/null @@ -1,100 +0,0 @@ -/** - * Copyright 2021 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 { - prefix = "${var.environment_code}_svpc" - access_level_name = "alp_${local.prefix}_members_${random_id.random_access_level_suffix.hex}" - access_level_name_dry_run = "alp_${local.prefix}_members_dry_run_${random_id.random_access_level_suffix.hex}" - perimeter_name = "sp_${local.prefix}_default_perimeter_${random_id.random_access_level_suffix.hex}" -} - -resource "random_id" "random_access_level_suffix" { - byte_length = 2 -} - -module "access_level" { - source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 6.0" - - description = "${local.prefix} Access Level for use in an enforced perimeter" - policy = var.access_context_manager_policy_id - name = local.access_level_name - members = var.members -} - -module "access_level_dry_run" { - source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 6.0" - - description = "${local.prefix} Access Level for testing with a dry run perimeter" - policy = var.access_context_manager_policy_id - name = local.access_level_name_dry_run - members = var.members_dry_run -} - -resource "time_sleep" "wait_vpc_sc_propagation" { - create_duration = "60s" - destroy_duration = "60s" - - depends_on = [ - module.main, - google_compute_global_address.private_service_access_address, - google_service_networking_connection.private_vpc_connection, - module.region1_router1, - module.region1_router2, - module.region2_router1, - module.region2_router2, - module.private_service_connect, - google_dns_policy.default_policy, - module.peering_zone, - module.firewall_rules, - google_compute_router.nat_router_region1, - google_compute_address.nat_external_addresses1, - google_compute_router_nat.nat_external_addresses_region1, - google_compute_router.nat_router_region2, - google_compute_address.nat_external_addresses_region2, - google_compute_router_nat.egress_nat_region2, - ] -} - -module "regular_service_perimeter" { - source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" - version = "~> 6.0" - - policy = var.access_context_manager_policy_id - perimeter_name = local.perimeter_name - description = "Default VPC Service Controls perimeter" - - # configurations for a perimeter in enforced mode. - resources = var.enforce_vpcsc ? [var.project_number] : [] - access_levels = var.enforce_vpcsc ? [module.access_level.name] : [] - restricted_services = var.enforce_vpcsc ? var.restricted_services : [] - vpc_accessible_services = var.enforce_vpcsc ? ["RESTRICTED-SERVICES"] : [] - ingress_policies = var.enforce_vpcsc ? var.ingress_policies : [] - egress_policies = var.enforce_vpcsc ? var.egress_policies : [] - - # configurations for a perimeter in dry run mode. - resources_dry_run = [var.project_number] - access_levels_dry_run = [module.access_level_dry_run.name] - restricted_services_dry_run = var.restricted_services_dry_run - vpc_accessible_services_dry_run = ["RESTRICTED-SERVICES"] - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies_dry_run = var.egress_policies_dry_run - - depends_on = [ - time_sleep.wait_vpc_sc_propagation - ] -} diff --git a/3-networks-svpc/modules/shared_vpc/variables.tf b/3-networks-svpc/modules/shared_vpc/variables.tf index 6342467f2..cbfb0f7b9 100644 --- a/3-networks-svpc/modules/shared_vpc/variables.tf +++ b/3-networks-svpc/modules/shared_vpc/variables.tf @@ -153,71 +153,8 @@ variable "windows_activation_enabled" { default = false } -variable "members" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "members_dry_run" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "restricted_services" { - type = list(string) - description = "List of services to restrict in an enforced perimeter." -} - -variable "restricted_services_dry_run" { - type = list(string) - description = "List of services to restrict in a dry-run perimeter." -} - variable "enable_all_vpc_internal_traffic" { type = bool description = "Enable firewall policy rule to allow internal traffic (ingress and egress)." default = false } - -variable "enforce_vpcsc" { - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." - type = bool - default = false -} - -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - From 6d1421ef6e64ad445269e19a1411180240df9e8e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 16:21:54 -0300 Subject: [PATCH 022/114] rm vpc-sc --- .../common.auto.example.tfvars | 5 - .../envs/development/README.md | 10 - .../envs/development/main.tf | 3 - .../envs/development/outputs.tf | 19 -- .../envs/development/variables.tf | 48 ----- .../envs/nonproduction/README.md | 10 - .../envs/nonproduction/main.tf | 36 ++-- .../envs/nonproduction/outputs.tf | 20 -- .../envs/nonproduction/variables.tf | 48 ----- .../envs/production/README.md | 10 - .../envs/production/main.tf | 36 ++-- .../envs/production/outputs.tf | 20 -- .../envs/production/variables.tf | 48 ----- .../envs/shared/README.md | 4 - 3-networks-hub-and-spoke/envs/shared/main.tf | 17 -- .../envs/shared/net-hubs.tf | 175 ++---------------- .../envs/shared/variables.tf | 29 --- .../modules/base_env/README.md | 12 -- .../modules/base_env/main.tf | 160 +--------------- .../modules/base_env/outputs.tf | 20 -- .../modules/base_env/variables.tf | 61 ------ .../modules/shared_vpc/README.md | 13 -- .../modules/shared_vpc/outputs.tf | 20 -- .../modules/shared_vpc/service_control.tf | 119 ------------ .../modules/shared_vpc/variables.tf | 62 ------- 25 files changed, 54 insertions(+), 951 deletions(-) delete mode 100644 3-networks-hub-and-spoke/modules/shared_vpc/service_control.tf diff --git a/3-networks-hub-and-spoke/common.auto.example.tfvars b/3-networks-hub-and-spoke/common.auto.example.tfvars index 9ce52ac7c..8181253d1 100644 --- a/3-networks-hub-and-spoke/common.auto.example.tfvars +++ b/3-networks-hub-and-spoke/common.auto.example.tfvars @@ -17,11 +17,6 @@ // The DNS name of peering managed zone. Must end with a period. domain = "example.com." -// Update the following line and add you email in the perimeter_additional_members list. -// You must be in this list to be able to view/access resources in the project protected by the VPC service controls. - -perimeter_additional_members = ["user:YOUR-USER-EMAIL@example.com"] - remote_state_bucket = "REMOTE_STATE_BUCKET" //enable_hub_and_spoke_transitivity = true diff --git a/3-networks-hub-and-spoke/envs/development/README.md b/3-networks-hub-and-spoke/envs/development/README.md index bd29e7c80..6039fc7f8 100644 --- a/3-networks-hub-and-spoke/envs/development/README.md +++ b/3-networks-hub-and-spoke/envs/development/README.md @@ -17,13 +17,7 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -32,12 +26,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| | access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/envs/development/main.tf b/3-networks-hub-and-spoke/envs/development/main.tf index 1b5b2c35f..e18b8187a 100644 --- a/3-networks-hub-and-spoke/envs/development/main.tf +++ b/3-networks-hub-and-spoke/envs/development/main.tf @@ -47,12 +47,9 @@ module "base_env" { env = local.env environment_code = local.environment_code access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - ingress_policies = var.ingress_policies - egress_policies = var.egress_policies enable_partner_interconnect = false enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity private_service_cidr = local.private_service_cidr diff --git a/3-networks-hub-and-spoke/envs/development/outputs.tf b/3-networks-hub-and-spoke/envs/development/outputs.tf index 7dacea96e..6e6c5b4eb 100644 --- a/3-networks-hub-and-spoke/envs/development/outputs.tf +++ b/3-networks-hub-and-spoke/envs/development/outputs.tf @@ -54,22 +54,3 @@ output "subnets_secondary_ranges" { description = "The secondary ranges associated with these subnets" } -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-hub-and-spoke/envs/development/variables.tf b/3-networks-hub-and-spoke/envs/development/variables.tf index cf3061211..614135775 100644 --- a/3-networks-hub-and-spoke/envs/development/variables.tf +++ b/3-networks-hub-and-spoke/envs/development/variables.tf @@ -35,54 +35,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/envs/nonproduction/README.md b/3-networks-hub-and-spoke/envs/nonproduction/README.md index 3447d2f68..a01f37ef8 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/README.md +++ b/3-networks-hub-and-spoke/envs/nonproduction/README.md @@ -17,13 +17,7 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -32,12 +26,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| | access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/envs/nonproduction/main.tf b/3-networks-hub-and-spoke/envs/nonproduction/main.tf index 954060efc..bb6ebde05 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/main.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/main.tf @@ -44,25 +44,19 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.7" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + access_context_manager_policy_id = var.access_context_manager_policy_id + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.7" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf b/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf index 700e37837..0ec049063 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-hub-and-spoke/envs/nonproduction/variables.tf b/3-networks-hub-and-spoke/envs/nonproduction/variables.tf index cf3061211..614135775 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/variables.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/variables.tf @@ -35,54 +35,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/envs/production/README.md b/3-networks-hub-and-spoke/envs/production/README.md index e1e62e277..480f30e16 100644 --- a/3-networks-hub-and-spoke/envs/production/README.md +++ b/3-networks-hub-and-spoke/envs/production/README.md @@ -17,13 +17,7 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -32,12 +26,8 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| | access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | -| access\_level\_name | Access context manager access level name | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/envs/production/main.tf b/3-networks-hub-and-spoke/envs/production/main.tf index 9cf7ffdb3..f4f56e560 100644 --- a/3-networks-hub-and-spoke/envs/production/main.tf +++ b/3-networks-hub-and-spoke/envs/production/main.tf @@ -44,25 +44,19 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - perimeter_additional_members = var.perimeter_additional_members - perimeter_additional_members_dry_run = var.perimeter_additional_members_dry_run - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - ingress_policies = var.ingress_policies - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies = var.egress_policies - egress_policies_dry_run = var.egress_policies_dry_run - enable_partner_interconnect = false - enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.8" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + access_context_manager_policy_id = var.access_context_manager_policy_id + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.8" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-hub-and-spoke/envs/production/outputs.tf b/3-networks-hub-and-spoke/envs/production/outputs.tf index 700e37837..0ec049063 100644 --- a/3-networks-hub-and-spoke/envs/production/outputs.tf +++ b/3-networks-hub-and-spoke/envs/production/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.base_env.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.base_env.access_level_name - description = "Access context manager access level name" -} - -output "access_level_name_dry_run" { - value = module.base_env.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.base_env.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.base_env.service_perimeter_name - description = "Access context manager service perimeter name" -} diff --git a/3-networks-hub-and-spoke/envs/production/variables.tf b/3-networks-hub-and-spoke/envs/production/variables.tf index cf3061211..614135775 100644 --- a/3-networks-hub-and-spoke/envs/production/variables.tf +++ b/3-networks-hub-and-spoke/envs/production/variables.tf @@ -35,54 +35,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/envs/shared/README.md b/3-networks-hub-and-spoke/envs/shared/README.md index 4dce69797..cd823fd06 100644 --- a/3-networks-hub-and-spoke/envs/shared/README.md +++ b/3-networks-hub-and-spoke/envs/shared/README.md @@ -14,11 +14,9 @@ The purpose of this step is to set up the global [DNS Hub](https://cloud.google. |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | bgp\_asn\_dns | BGP Autonomous System Number (ASN). | `number` | `64667` | no | -| custom\_restricted\_services | List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | dns\_enable\_logging | Toggle DNS logging for VPC DNS. | `bool` | `true` | no | | dns\_vpc\_flow\_logs | enable\_logging: set to true to enable VPC flow logging for the subnetworks.
aggregation\_interval: Toggles the aggregation interval for collecting flow logs. Increasing the interval time will reduce the amount of generated flow logs for long lasting connections. Possible values are: INTERVAL\_5\_SEC, INTERVAL\_30\_SEC, INTERVAL\_1\_MIN, INTERVAL\_5\_MIN, INTERVAL\_10\_MIN, INTERVAL\_15\_MIN.
flow\_sampling: Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported. The value of the field must be in [0, 1].
metadata: Configures whether metadata fields should be added to the reported VPC flow logs. Possible values are: EXCLUDE\_ALL\_METADATA, INCLUDE\_ALL\_METADATA, CUSTOM\_METADATA.
metadata\_fields: ist of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and "metadata" is set to CUSTOM\_METADATA.
filter\_expr: Export filter used to define which VPC flow logs should be logged, as as CEL expression. See https://cloud.google.com/vpc/docs/flow-logs#filtering for details on how to format this field. |
object({
enable_logging = optional(string, "true")
aggregation_interval = optional(string, "INTERVAL_5_SEC")
flow_sampling = optional(string, "0.5")
metadata = optional(string, "INCLUDE_ALL_METADATA")
metadata_fields = optional(list(string), [])
filter_expr = optional(string, "true")
})
| `{}` | no | | domain | The DNS name of forwarding managed zone, for instance 'example.com'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference), each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_dedicated\_interconnect | Enable Dedicated Interconnect in the environment. | `bool` | `false` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_partner\_interconnect | Enable Partner Interconnect in the environment. | `bool` | `false` | no | @@ -31,8 +29,6 @@ The purpose of this step is to set up the global [DNS Hub](https://cloud.google. | hub\_nat\_num\_addresses\_region1 | Number of external IPs to reserve for first Cloud NAT in Shared Hub. | `number` | `2` | no | | hub\_nat\_num\_addresses\_region2 | Number of external IPs to reserve for second Cloud NAT in Shared Hub. | `number` | `2` | no | | hub\_windows\_activation\_enabled | Enable Windows license activation for Windows workloads in Shared Hub. | `bool` | `false` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference), each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the Shared perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | n/a | yes | | preactivate\_partner\_interconnect | Preactivate Partner Interconnect VLAN attachment in the environment. | `bool` | `false` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | n/a | yes | diff --git a/3-networks-hub-and-spoke/envs/shared/main.tf b/3-networks-hub-and-spoke/envs/shared/main.tf index 891fa4eba..be349ba3f 100644 --- a/3-networks-hub-and-spoke/envs/shared/main.tf +++ b/3-networks-hub-and-spoke/envs/shared/main.tf @@ -19,21 +19,4 @@ locals { environment_code = "c" bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" dns_bgp_asn_number = var.enable_partner_interconnect ? "16550" : var.bgp_asn_dns - - dedicated_interconnect_egress_policy = var.enable_dedicated_interconnect ? [ - { - "from" = { - "identity_type" = "" - "identities" = ["serviceAccount:${local.networks_service_account}"] - }, - "to" = { - "resources" = ["projects/${local.interconnect_project_number}"] - "operations" = { - "compute.googleapis.com" = { - "methods" = ["*"] - } - } - } - }, - ] : [] } diff --git a/3-networks-hub-and-spoke/envs/shared/net-hubs.tf b/3-networks-hub-and-spoke/envs/shared/net-hubs.tf index 084f7d386..e887a39d2 100644 --- a/3-networks-hub-and-spoke/envs/shared/net-hubs.tf +++ b/3-networks-hub-and-spoke/envs/shared/net-hubs.tf @@ -25,133 +25,6 @@ locals { (local.default_region2) = "10.27.0.0/23" } - supported_restricted_service = [ - "accessapproval.googleapis.com", - "adsdatahub.googleapis.com", - "aiplatform.googleapis.com", - "alloydb.googleapis.com", - "alpha-documentai.googleapis.com", - "analyticshub.googleapis.com", - "apigee.googleapis.com", - "apigeeconnect.googleapis.com", - "artifactregistry.googleapis.com", - "assuredworkloads.googleapis.com", - "automl.googleapis.com", - "baremetalsolution.googleapis.com", - "batch.googleapis.com", - "bigquery.googleapis.com", - "bigquerydatapolicy.googleapis.com", - "bigquerydatatransfer.googleapis.com", - "bigquerymigration.googleapis.com", - "bigqueryreservation.googleapis.com", - "bigtable.googleapis.com", - "binaryauthorization.googleapis.com", - "cloud.googleapis.com", - "cloudasset.googleapis.com", - "cloudbuild.googleapis.com", - "clouddebugger.googleapis.com", - "clouddeploy.googleapis.com", - "clouderrorreporting.googleapis.com", - "cloudfunctions.googleapis.com", - "cloudkms.googleapis.com", - "cloudprofiler.googleapis.com", - "cloudresourcemanager.googleapis.com", - "cloudscheduler.googleapis.com", - "cloudsearch.googleapis.com", - "cloudtrace.googleapis.com", - "composer.googleapis.com", - "compute.googleapis.com", - "connectgateway.googleapis.com", - "contactcenterinsights.googleapis.com", - "container.googleapis.com", - "containeranalysis.googleapis.com", - "containerfilesystem.googleapis.com", - "containerregistry.googleapis.com", - "containerthreatdetection.googleapis.com", - "datacatalog.googleapis.com", - "dataflow.googleapis.com", - "datafusion.googleapis.com", - "datamigration.googleapis.com", - "dataplex.googleapis.com", - "dataproc.googleapis.com", - "datastream.googleapis.com", - "dialogflow.googleapis.com", - "dlp.googleapis.com", - "dns.googleapis.com", - "documentai.googleapis.com", - "domains.googleapis.com", - "eventarc.googleapis.com", - "file.googleapis.com", - "firebaseappcheck.googleapis.com", - "firebaserules.googleapis.com", - "firestore.googleapis.com", - "gameservices.googleapis.com", - "gkebackup.googleapis.com", - "gkeconnect.googleapis.com", - "gkehub.googleapis.com", - "healthcare.googleapis.com", - "iam.googleapis.com", - "iamcredentials.googleapis.com", - "iaptunnel.googleapis.com", - "ids.googleapis.com", - "integrations.googleapis.com", - "kmsinventory.googleapis.com", - "krmapihosting.googleapis.com", - "language.googleapis.com", - "lifesciences.googleapis.com", - "logging.googleapis.com", - "managedidentities.googleapis.com", - "memcache.googleapis.com", - "meshca.googleapis.com", - "meshconfig.googleapis.com", - "metastore.googleapis.com", - "ml.googleapis.com", - "monitoring.googleapis.com", - "networkconnectivity.googleapis.com", - "networkmanagement.googleapis.com", - "networksecurity.googleapis.com", - "networkservices.googleapis.com", - "notebooks.googleapis.com", - "opsconfigmonitoring.googleapis.com", - "orgpolicy.googleapis.com", - "osconfig.googleapis.com", - "oslogin.googleapis.com", - "privateca.googleapis.com", - "pubsub.googleapis.com", - "pubsublite.googleapis.com", - "recaptchaenterprise.googleapis.com", - "recommender.googleapis.com", - "redis.googleapis.com", - "retail.googleapis.com", - "run.googleapis.com", - "secretmanager.googleapis.com", - "servicecontrol.googleapis.com", - "servicedirectory.googleapis.com", - "spanner.googleapis.com", - "speakerid.googleapis.com", - "speech.googleapis.com", - "sqladmin.googleapis.com", - "storage.googleapis.com", - "storagetransfer.googleapis.com", - "sts.googleapis.com", - "texttospeech.googleapis.com", - "timeseriesinsights.googleapis.com", - "tpu.googleapis.com", - "trafficdirector.googleapis.com", - "transcoder.googleapis.com", - "translate.googleapis.com", - "videointelligence.googleapis.com", - "vision.googleapis.com", - "visionai.googleapis.com", - "vmmigration.googleapis.com", - "vpcaccess.googleapis.com", - "webrisk.googleapis.com", - "workflows.googleapis.com", - "workstations.googleapis.com", - ] - - restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service - restricted_services_dry_run = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service } /****************************************** @@ -166,32 +39,20 @@ module "shared_vpc" { environment_code = local.environment_code private_service_connect_ip = "10.17.0.5" access_context_manager_policy_id = var.access_context_manager_policy_id - restricted_services = local.restricted_services - restricted_services_dry_run = local.restricted_services_dry_run - members = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - members_dry_run = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - bgp_asn_subnet = local.bgp_asn_number - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - dns_enable_inbound_forwarding = var.hub_dns_enable_inbound_forwarding - dns_enable_logging = var.hub_dns_enable_logging - firewall_enable_logging = var.hub_firewall_enable_logging - nat_enabled = var.hub_nat_enabled - nat_bgp_asn = var.hub_nat_bgp_asn - nat_num_addresses_region1 = var.hub_nat_num_addresses_region1 - nat_num_addresses_region2 = var.hub_nat_num_addresses_region2 - windows_activation_enabled = var.hub_windows_activation_enabled - target_name_server_addresses = var.target_name_server_addresses - mode = "hub" + bgp_asn_subnet = local.bgp_asn_number + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + dns_enable_inbound_forwarding = var.hub_dns_enable_inbound_forwarding + dns_enable_logging = var.hub_dns_enable_logging + firewall_enable_logging = var.hub_firewall_enable_logging + nat_enabled = var.hub_nat_enabled + nat_bgp_asn = var.hub_nat_bgp_asn + nat_num_addresses_region1 = var.hub_nat_num_addresses_region1 + nat_num_addresses_region2 = var.hub_nat_num_addresses_region2 + windows_activation_enabled = var.hub_windows_activation_enabled + target_name_server_addresses = var.target_name_server_addresses + mode = "hub" subnets = [ { @@ -240,12 +101,4 @@ module "shared_vpc" { } ] secondary_ranges = {} - - egress_policies = distinct(concat( - local.dedicated_interconnect_egress_policy, - var.egress_policies - )) - - ingress_policies = var.ingress_policies - } diff --git a/3-networks-hub-and-spoke/envs/shared/variables.tf b/3-networks-hub-and-spoke/envs/shared/variables.tf index 42bcc7530..8bad48e2a 100644 --- a/3-networks-hub-and-spoke/envs/shared/variables.tf +++ b/3-networks-hub-and-spoke/envs/shared/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the Shared perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) -} - variable "access_context_manager_policy_id" { type = number description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." @@ -169,30 +164,6 @@ variable "enable_hub_and_spoke_transitivity" { default = false } -variable "custom_restricted_services" { - description = "List of custom services to be protected by the VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference), each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference), each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/modules/base_env/README.md b/3-networks-hub-and-spoke/modules/base_env/README.md index 908261758..bca9b7489 100644 --- a/3-networks-hub-and-spoke/modules/base_env/README.md +++ b/3-networks-hub-and-spoke/modules/base_env/README.md @@ -4,22 +4,14 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | -| custom\_restricted\_services | List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | -| custom\_restricted\_services\_dry\_run | List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected. | `list(string)` | `[]` | no | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_dedicated\_interconnect | Enable Dedicated Interconnect in the environment. | `bool` | `false` | no | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_partner\_interconnect | Enable Partner Interconnect in the environment. | `bool` | `false` | no | | env | The environment to prepare (ex. development) | `string` | n/a | yes | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization (ex. d). | `string` | n/a | yes | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| perimeter\_additional\_members | The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | -| perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Shared Vpc. | `string` | n/a | yes | | private\_service\_connect\_ip | The subnet internal IP to be used as the private service connect endpoint in the Shared VPC | `string` | n/a | yes | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | @@ -34,12 +26,8 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | shared\_vpc\_host\_project\_id | The host project ID | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | diff --git a/3-networks-hub-and-spoke/modules/base_env/main.tf b/3-networks-hub-and-spoke/modules/base_env/main.tf index 60e34e5af..523b30304 100644 --- a/3-networks-hub-and-spoke/modules/base_env/main.tf +++ b/3-networks-hub-and-spoke/modules/base_env/main.tf @@ -20,139 +20,12 @@ locals { subnet_aggregates = ["10.8.0.0/18", "10.9.0.0/18", "100.72.0.0/18", "100.73.0.0/18"] hub_subnet_ranges = ["10.8.0.0/24", "10.9.0.0/24"] - - supported_restricted_service = [ - "accessapproval.googleapis.com", - "adsdatahub.googleapis.com", - "aiplatform.googleapis.com", - "alloydb.googleapis.com", - "alpha-documentai.googleapis.com", - "analyticshub.googleapis.com", - "apigee.googleapis.com", - "apigeeconnect.googleapis.com", - "artifactregistry.googleapis.com", - "assuredworkloads.googleapis.com", - "automl.googleapis.com", - "baremetalsolution.googleapis.com", - "batch.googleapis.com", - "bigquery.googleapis.com", - "bigquerydatapolicy.googleapis.com", - "bigquerydatatransfer.googleapis.com", - "bigquerymigration.googleapis.com", - "bigqueryreservation.googleapis.com", - "bigtable.googleapis.com", - "binaryauthorization.googleapis.com", - "cloud.googleapis.com", - "cloudasset.googleapis.com", - "cloudbuild.googleapis.com", - "clouddebugger.googleapis.com", - "clouddeploy.googleapis.com", - "clouderrorreporting.googleapis.com", - "cloudfunctions.googleapis.com", - "cloudkms.googleapis.com", - "cloudprofiler.googleapis.com", - "cloudresourcemanager.googleapis.com", - "cloudscheduler.googleapis.com", - "cloudsearch.googleapis.com", - "cloudtrace.googleapis.com", - "composer.googleapis.com", - "compute.googleapis.com", - "connectgateway.googleapis.com", - "contactcenterinsights.googleapis.com", - "container.googleapis.com", - "containeranalysis.googleapis.com", - "containerfilesystem.googleapis.com", - "containerregistry.googleapis.com", - "containerthreatdetection.googleapis.com", - "datacatalog.googleapis.com", - "dataflow.googleapis.com", - "datafusion.googleapis.com", - "datamigration.googleapis.com", - "dataplex.googleapis.com", - "dataproc.googleapis.com", - "datastream.googleapis.com", - "dialogflow.googleapis.com", - "dlp.googleapis.com", - "dns.googleapis.com", - "documentai.googleapis.com", - "domains.googleapis.com", - "eventarc.googleapis.com", - "file.googleapis.com", - "firebaseappcheck.googleapis.com", - "firebaserules.googleapis.com", - "firestore.googleapis.com", - "gameservices.googleapis.com", - "gkebackup.googleapis.com", - "gkeconnect.googleapis.com", - "gkehub.googleapis.com", - "healthcare.googleapis.com", - "iam.googleapis.com", - "iamcredentials.googleapis.com", - "iaptunnel.googleapis.com", - "ids.googleapis.com", - "integrations.googleapis.com", - "kmsinventory.googleapis.com", - "krmapihosting.googleapis.com", - "language.googleapis.com", - "lifesciences.googleapis.com", - "logging.googleapis.com", - "managedidentities.googleapis.com", - "memcache.googleapis.com", - "meshca.googleapis.com", - "meshconfig.googleapis.com", - "metastore.googleapis.com", - "ml.googleapis.com", - "monitoring.googleapis.com", - "networkconnectivity.googleapis.com", - "networkmanagement.googleapis.com", - "networksecurity.googleapis.com", - "networkservices.googleapis.com", - "notebooks.googleapis.com", - "opsconfigmonitoring.googleapis.com", - "orgpolicy.googleapis.com", - "osconfig.googleapis.com", - "oslogin.googleapis.com", - "privateca.googleapis.com", - "pubsub.googleapis.com", - "pubsublite.googleapis.com", - "recaptchaenterprise.googleapis.com", - "recommender.googleapis.com", - "redis.googleapis.com", - "retail.googleapis.com", - "run.googleapis.com", - "secretmanager.googleapis.com", - "servicecontrol.googleapis.com", - "servicedirectory.googleapis.com", - "spanner.googleapis.com", - "speakerid.googleapis.com", - "speech.googleapis.com", - "sqladmin.googleapis.com", - "storage.googleapis.com", - "storagetransfer.googleapis.com", - "sts.googleapis.com", - "texttospeech.googleapis.com", - "timeseriesinsights.googleapis.com", - "tpu.googleapis.com", - "trafficdirector.googleapis.com", - "transcoder.googleapis.com", - "translate.googleapis.com", - "videointelligence.googleapis.com", - "vision.googleapis.com", - "visionai.googleapis.com", - "vmmigration.googleapis.com", - "vpcaccess.googleapis.com", - "webrisk.googleapis.com", - "workflows.googleapis.com", - "workstations.googleapis.com", - ] - - restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service - restricted_services_dry_run = length(var.custom_restricted_services_dry_run) != 0 ? var.custom_restricted_services : local.supported_restricted_service } /****************************************** Shared VPC *****************************************/ + module "shared_vpc" { source = "../shared_vpc" @@ -162,28 +35,14 @@ module "shared_vpc" { net_hub_project_number = local.net_hub_project_number environment_code = var.environment_code access_context_manager_policy_id = var.access_context_manager_policy_id - restricted_services = local.restricted_services - restricted_services_dry_run = local.restricted_services_dry_run - members = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - members_dry_run = distinct(concat([ - "serviceAccount:${local.networks_service_account}", - "serviceAccount:${local.projects_service_account}", - "serviceAccount:${local.organization_service_account}", - ], var.perimeter_additional_members)) - private_service_cidr = var.private_service_cidr - private_service_connect_ip = var.private_service_connect_ip - ingress_policies = var.ingress_policies - egress_policies = var.egress_policies - bgp_asn_subnet = local.bgp_asn_number - default_region1 = var.default_region1 - default_region2 = var.default_region2 - domain = var.domain - mode = "spoke" - target_name_server_addresses = var.target_name_server_addresses + private_service_cidr = var.private_service_cidr + private_service_connect_ip = var.private_service_connect_ip + bgp_asn_subnet = local.bgp_asn_number + default_region1 = var.default_region1 + default_region2 = var.default_region2 + domain = var.domain + mode = "spoke" + target_name_server_addresses = var.target_name_server_addresses subnets = [ { @@ -233,5 +92,6 @@ module "shared_vpc" { ] secondary_ranges = { "sb-${var.environment_code}-svpc-${var.default_region1}" = var.subnet_secondary_ranges[var.default_region1] + "sb-${var.environment_code}-svpc-${var.default_region1}" = var.subnet_secondary_ranges[var.default_region1] } } diff --git a/3-networks-hub-and-spoke/modules/base_env/outputs.tf b/3-networks-hub-and-spoke/modules/base_env/outputs.tf index e4e7217d9..ec03126b9 100644 --- a/3-networks-hub-and-spoke/modules/base_env/outputs.tf +++ b/3-networks-hub-and-spoke/modules/base_env/outputs.tf @@ -53,23 +53,3 @@ output "subnets_secondary_ranges" { value = module.shared_vpc.subnets_secondary_ranges description = "The secondary ranges associated with these subnets" } - -output "access_level_name" { - value = module.shared_vpc.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = module.shared_vpc.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = module.shared_vpc.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = module.shared_vpc.service_perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} diff --git a/3-networks-hub-and-spoke/modules/base_env/variables.tf b/3-networks-hub-and-spoke/modules/base_env/variables.tf index 3c9ce405c..9913080c8 100644 --- a/3-networks-hub-and-spoke/modules/base_env/variables.tf +++ b/3-networks-hub-and-spoke/modules/base_env/variables.tf @@ -116,67 +116,6 @@ EOT default = {} } -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "perimeter_additional_members" { - description = "The list of additional members to be added to the enforced perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - -variable "perimeter_additional_members_dry_run" { - description = "The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the restricted perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`." - type = list(string) - default = [] -} - - -variable "custom_restricted_services" { - description = "List of custom services to be protected by the enforced VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - -variable "custom_restricted_services_dry_run" { - description = "List of custom services to be protected by the dry-run VPC-SC perimeter. If empty, all supported services (https://cloud.google.com/vpc-service-controls/docs/supported-products) will be protected." - type = list(string) - default = [] -} - variable "tfc_org_name" { description = "Name of the TFC organization" type = string diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/README.md b/3-networks-hub-and-spoke/modules/shared_vpc/README.md index 74c4627d9..3334081ea 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/README.md +++ b/3-networks-hub-and-spoke/modules/shared_vpc/README.md @@ -10,17 +10,10 @@ | dns\_enable\_inbound\_forwarding | Toggle inbound query forwarding for VPC DNS. | `bool` | `true` | no | | dns\_enable\_logging | Toggle DNS logging for VPC DNS. | `bool` | `true` | no | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | -| egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | | enable\_all\_vpc\_internal\_traffic | Enable firewall policy rule to allow internal traffic (ingress and egress). | `bool` | `false` | no | | enable\_transitivity\_traffic | Enable a firewall policy rule to allow traffic between Hub and Spokes (ingress only). | `bool` | `true` | no | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | `bool` | `false` | no | | environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization. | `string` | n/a | yes | | firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls. | `bool` | `true` | no | -| ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
from = any
to = any
}))
| `[]` | no | -| members | An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | -| members\_dry\_run | An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid} | `list(string)` | n/a | yes | | mode | Network deployment mode, should be set to `hub` or `spoke` when `enable_hub_and_spoke` architecture chosen, keep as `null` otherwise. | `string` | `null` | no | | nat\_bgp\_asn | BGP ASN for NAT cloud routes. If NAT is enabled this variable value must be a value in ranges [64512..65534] or [4200000000..4294967294]. | `number` | `64512` | no | | nat\_enabled | Toggle creation of NAT cloud router. | `bool` | `false` | no | @@ -32,8 +25,6 @@ | private\_service\_connect\_ip | Internal IP to be used as the private service connect endpoint. | `string` | n/a | yes | | project\_id | Project ID for Shared VPC. | `string` | n/a | yes | | project\_number | Project number for Shared VPC. | `number` | n/a | yes | -| restricted\_services | List of services to restrict in an enforced perimeter. | `list(string)` | n/a | yes | -| restricted\_services\_dry\_run | List of services to restrict in a dry-run perimeter. | `list(string)` | n/a | yes | | secondary\_ranges | Secondary ranges that will be used in some of the subnets | `map(list(object({ range_name = string, ip_cidr_range = string })))` | `{}` | no | | subnets | The list of subnets being created |
list(object({
subnet_name = string
subnet_ip = string
subnet_region = string
subnet_private_access = optional(string, "false")
subnet_private_ipv6_access = optional(string)
subnet_flow_logs = optional(string, "false")
subnet_flow_logs_interval = optional(string, "INTERVAL_5_SEC")
subnet_flow_logs_sampling = optional(string, "0.5")
subnet_flow_logs_metadata = optional(string, "INCLUDE_ALL_METADATA")
subnet_flow_logs_filter = optional(string, "true")
subnet_flow_logs_metadata_fields = optional(list(string), [])
description = optional(string)
purpose = optional(string)
role = optional(string)
stack_type = optional(string)
ipv6_access_type = optional(string)
}))
| `[]` | no | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | n/a | yes | @@ -43,10 +34,7 @@ | Name | Description | |------|-------------| -| access\_level\_name | Access context manager access level name for the enforced perimeter | -| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | | dns\_policy | The name of the DNS policy being created | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | | firewall\_policy | Policy created for firewall policy rules. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | @@ -54,7 +42,6 @@ | region1\_router2 | Router 2 for Region 1 | | region2\_router1 | Router 1 for Region 2 | | region2\_router2 | Router 2 for Region 2 | -| service\_perimeter\_name | Access context manager service perimeter name for the enforced perimeter | | subnets\_ips | The IPs and CIDRs of the subnets being created | | subnets\_names | The names of the subnets being created | | subnets\_regions | The region where the subnets will be created | diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf b/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf index 617c987fd..7ff41daca 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf +++ b/3-networks-hub-and-spoke/modules/shared_vpc/outputs.tf @@ -78,23 +78,3 @@ output "firewall_policy" { value = module.firewall_rules.fw_policy[0].name description = "Policy created for firewall policy rules." } - -output "access_level_name" { - value = local.access_level_name - description = "Access context manager access level name for the enforced perimeter" -} - -output "access_level_name_dry_run" { - value = local.access_level_name_dry_run - description = "Access context manager access level name for the dry-run perimeter" -} - -output "enforce_vpcsc" { - value = var.enforce_vpcsc - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." -} - -output "service_perimeter_name" { - value = local.perimeter_name - description = "Access context manager service perimeter name for the enforced perimeter" -} diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/service_control.tf b/3-networks-hub-and-spoke/modules/shared_vpc/service_control.tf deleted file mode 100644 index 42921e0f5..000000000 --- a/3-networks-hub-and-spoke/modules/shared_vpc/service_control.tf +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright 2021 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 { - prefix = "${var.environment_code}_shared_vpc" - access_level_name = "alp_${local.prefix}_members_${random_id.random_access_level_suffix.hex}" - access_level_name_dry_run = "alp_${local.prefix}_members_dry_run_${random_id.random_access_level_suffix.hex}" - perimeter_name = "sp_${local.prefix}_default_perimeter_${random_id.random_access_level_suffix.hex}" - bridge_name = "spb_c_to_${local.prefix}_bridge_${random_id.random_access_level_suffix.hex}" -} - -resource "random_id" "random_access_level_suffix" { - byte_length = 2 -} - -module "access_level" { - source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 6.0" - - description = "${local.prefix} Access Level" - policy = var.access_context_manager_policy_id - name = local.access_level_name - members = var.members -} - -module "access_level_dry_run" { - source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 6.0" - - description = "${local.prefix} Access Level for testing with a dry run perimeter" - policy = var.access_context_manager_policy_id - name = local.access_level_name_dry_run - members = var.members_dry_run -} - -resource "time_sleep" "wait_vpc_sc_propagation" { - create_duration = "60s" - destroy_duration = "60s" - - depends_on = [ - module.main, - module.peering, - google_compute_global_address.private_service_access_address, - google_service_networking_connection.private_vpc_connection, - module.region1_router1, - module.region1_router2, - module.region2_router1, - module.region2_router2, - module.private_service_connect, - google_dns_policy.default_policy, - module.peering_zone, - module.firewall_rules, - google_compute_router.nat_router_region1, - google_compute_address.nat_external_addresses1, - google_compute_router_nat.nat_external_addresses_region1, - google_compute_router.nat_router_region2, - google_compute_address.nat_external_addresses_region2, - google_compute_router_nat.egress_nat_region2, - ] -} - -module "regular_service_perimeter" { - source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" - version = "~> 6.0" - - policy = var.access_context_manager_policy_id - perimeter_name = local.perimeter_name - description = "Default VPC Service Controls perimeter" - - # configurations for a perimeter in enforced mode. - resources = var.enforce_vpcsc ? [var.project_number] : [] - access_levels = var.enforce_vpcsc ? [module.access_level.name] : [] - restricted_services = var.enforce_vpcsc ? var.restricted_services : [] - vpc_accessible_services = var.enforce_vpcsc ? ["RESTRICTED-SERVICES"] : [] - ingress_policies = var.enforce_vpcsc ? var.ingress_policies : [] - egress_policies = var.enforce_vpcsc ? var.egress_policies : [] - - # configurations for a perimeter in dry run mode. - resources_dry_run = [var.project_number] - access_levels_dry_run = [module.access_level_dry_run.name] - restricted_services_dry_run = var.restricted_services_dry_run - vpc_accessible_services_dry_run = ["RESTRICTED-SERVICES"] - ingress_policies_dry_run = var.ingress_policies_dry_run - egress_policies_dry_run = var.egress_policies_dry_run - - depends_on = [ - time_sleep.wait_vpc_sc_propagation - ] -} - -resource "google_access_context_manager_service_perimeter" "bridge_to_network_hub_perimeter" { - count = var.mode == "spoke" ? 1 : 0 - - perimeter_type = "PERIMETER_TYPE_BRIDGE" - parent = "accessPolicies/${var.access_context_manager_policy_id}" - name = "accessPolicies/${var.access_context_manager_policy_id}/servicePerimeters/${local.bridge_name}" - title = local.bridge_name - - use_explicit_dry_run_spec = var.enforce_vpcsc ? false : true - - status { - resources = var.enforce_vpcsc ? formatlist("projects/%s", [var.project_number, var.net_hub_project_number]) : [] - } - - depends_on = [module.regular_service_perimeter] -} diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf b/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf index b61d41451..cd4fa3a2d 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf +++ b/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf @@ -165,26 +165,6 @@ variable "windows_activation_enabled" { default = false } -variable "members" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in an enforced perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "members_dry_run" { - type = list(string) - description = "An allowed list of members (users, service accounts) for an access level in a dry run perimeter. The signed-in identity originating the request must be a part of one of the provided members. If not specified, a request may come from any user (logged in/not logged in, etc.). Formats: user:{emailid}, serviceAccount:{emailid}" -} - -variable "restricted_services" { - type = list(string) - description = "List of services to restrict in an enforced perimeter." -} - -variable "restricted_services_dry_run" { - type = list(string) - description = "List of services to restrict in a dry-run perimeter." -} - variable "enable_all_vpc_internal_traffic" { type = bool description = "Enable firewall policy rule to allow internal traffic (ingress and egress)." @@ -196,45 +176,3 @@ variable "enable_transitivity_traffic" { description = "Enable a firewall policy rule to allow traffic between Hub and Spokes (ingress only)." default = true } - -variable "enforce_vpcsc" { - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." - type = bool - default = false -} - -variable "egress_policies" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "egress_policies_dry_run" { - description = "A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress_from and egress_to.\n\nExample: `[{ from={ identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in an enforced perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} - -variable "ingress_policies_dry_run" { - description = "A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress_from and ingress_to.\n\nExample: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type=\"ID_TYPE\" }, to={ resources=[], operations={ \"SRV_NAME\"={ OP_TYPE=[] }}}}]`\n\nValid Values:\n`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`\n`SRV_NAME` = \"`*`\" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)\n`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions)" - type = list(object({ - from = any - to = any - })) - default = [] -} From d7faa720aa30a149d12394e37e0c42aaef9da85e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 16:36:51 -0300 Subject: [PATCH 023/114] fix networks READMES --- 3-networks-hub-and-spoke/README.md | 38 +++++++++++------------------- 3-networks-svpc/README.md | 30 ++++++++--------------- 2 files changed, 24 insertions(+), 44 deletions(-) diff --git a/3-networks-hub-and-spoke/README.md b/3-networks-hub-and-spoke/README.md index 362ceb08c..6df4cd70a 100644 --- a/3-networks-hub-and-spoke/README.md +++ b/3-networks-hub-and-spoke/README.md @@ -193,18 +193,16 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` - **Note:** Make sure that you update the `perimeter_additional_members` variable with your user identity in order to be able to view/access resources in the project protected by the VPC Service Controls. - -1. Commit changes +2. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -1. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -1. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -1. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +3. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +4. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +5. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -214,26 +212,26 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -1. Run `init` and `plan` and review output for environment shared. +6. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -1. Run `validate` and check for violations. +7. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -1. Run `apply` shared. +8. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -1. Push your plan branch to trigger a plan for all environments. Because the +9. Push your plan branch to trigger a plan for all environments. Because the _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch)), pushing your _plan_ branch triggers _terraform plan_ but not _terraform apply_. Review the plan output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID @@ -241,7 +239,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push --set-upstream origin plan ``` -1. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +10. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -249,7 +247,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin production ``` -1. After production has been applied, apply development. +11. After production has been applied, apply development. 1. Merge changes to development. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID @@ -258,8 +256,8 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin development ``` -1. After development has been applied, apply nonproduction. -1. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +2. After development has been applied, apply nonproduction. +3. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -267,13 +265,13 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin nonproduction ``` -1. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +4. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -1. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. +5. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. ### Deploying with Jenkins @@ -445,11 +443,3 @@ Before executing the next stages, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` - -### (Optional) Enforce VPC Service Controls - -Because enabling VPC Service Controls can be a disruptive process, this repo configures VPC Service Controls perimeters in dry run mode by default. This configuration will service traffic that crosses the security perimeter (API requests that originate from inside your perimeter communicating with external resources, or API requests from external resources communicating with resources inside your perimeter) but still allow service traffic normally. - -When you are ready to enforce VPC Service Controls, we recommend that you review the guidance at [Best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable). After you have added the necessary exceptions and are confident that VPC Service Controls will not disrupt your intended operations, set the variable `enforce_vpcsc` under the module `shared_vpc` to `true` and re-apply this stage. Then re-apply the 4-projects stage, which will inherit the new setting and include those projects inside the enforced perimeter. - -When you need to make changes to an existing enforced perimeter, you can test safely by modifying the configuration of the dry run perimeter. This will log traffic denied by the dry run perimeter without impacting whether the enforced perimeter allows or denies traffic. diff --git a/3-networks-svpc/README.md b/3-networks-svpc/README.md index b8e3a29f2..e89b51c75 100644 --- a/3-networks-svpc/README.md +++ b/3-networks-svpc/README.md @@ -189,18 +189,16 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` - **Note:** Make sure that you update the `perimeter_additional_members` variable with your user identity in order to be able to view/access resources in the project protected by the VPC Service Controls. - -1. Commit changes +2. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -1. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -1. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -1. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +3. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +4. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +5. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -210,39 +208,39 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -1. Run `init` and `plan` and review output for environment shared. +6. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -1. Run `validate` and check for violations. +7. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -1. Run `apply` shared. +8. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -1. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. +9. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. ```bash git checkout -b production ``` -1. Run `init` and `plan` and review output for environment production. +10. Run `init` and `plan` and review output for environment production. ```bash ./tf-wrapper.sh init production ./tf-wrapper.sh plan production ``` -1. Run `apply` production. +11. Run `apply` production. ```bash ./tf-wrapper.sh apply production @@ -479,11 +477,3 @@ Before executing the next stages, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` - -### (Optional) Enforce VPC Service Controls - -Because enabling VPC Service Controls can be a disruptive process, this repo configures VPC Service Controls perimeters in dry run mode by default. This configuration will service traffic that crosses the security perimeter (API requests that originate from inside your perimeter communicating with external resources, or API requests from external resources communicating with resources inside your perimeter) but still allow service traffic normally. - -When you are ready to enforce VPC Service Controls, we recommend that you review the guidance at [Best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable). After you have added the necessary exceptions and are confident that VPC Service Controls will not disrupt your intended operations, set the variable `enforce_vpcsc` under the module `shared_vpc` to `true` and re-apply this stage. Then re-apply the 4-projects stage, which will inherit the new setting and include those projects inside the enforced perimeter. - -When you need to make changes to an existing enforced perimeter, you can test safely by modifying the configuration of the [dry run perimeter](https://cloud.google.com/vpc-service-controls/docs/dry-run-mode). This will log traffic denied by the dry run perimeter without impacting whether the enforced perimeter allows or denies traffic. From b1c3370e4d59656caafc57f6dfcce758d282e3b2 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 16:57:35 -0300 Subject: [PATCH 024/114] add projects to perimeter --- 4-projects/business_unit_1/shared/README.md | 1 + .../shared/example_infra_pipeline.tf | 8 +++++++- 4-projects/business_unit_1/shared/outputs.tf | 4 ++++ 4-projects/business_unit_1/shared/remote.tf | 3 +++ .../modules/base_env/example_floating_project.tf | 5 +++++ .../modules/base_env/example_peering_project.tf | 5 +++++ .../modules/base_env/example_shared_vpc_project.tf | 3 ++- 4-projects/modules/infra_pipelines/README.md | 2 -- 4-projects/modules/infra_pipelines/variables.tf | 13 ------------- 9 files changed, 27 insertions(+), 17 deletions(-) diff --git a/4-projects/business_unit_1/shared/README.md b/4-projects/business_unit_1/shared/README.md index 011c44625..00dd83ea7 100644 --- a/4-projects/business_unit_1/shared/README.md +++ b/4-projects/business_unit_1/shared/README.md @@ -16,6 +16,7 @@ | apply\_triggers\_id | CB apply triggers | | artifact\_buckets | GCS Buckets to store Cloud Build Artifacts | | cloudbuild\_project\_id | n/a | +| cloudbuild\_project\_number | n/a | | default\_region | Default region to create resources where applicable. | | enable\_cloudbuild\_deploy | Enable infra deployment using Cloud Build. | | log\_buckets | GCS Buckets to store Cloud Build logs | diff --git a/4-projects/business_unit_1/shared/example_infra_pipeline.tf b/4-projects/business_unit_1/shared/example_infra_pipeline.tf index 013b80bd4..3543a730d 100644 --- a/4-projects/business_unit_1/shared/example_infra_pipeline.tf +++ b/4-projects/business_unit_1/shared/example_infra_pipeline.tf @@ -15,7 +15,8 @@ */ locals { - repo_names = ["bu1-example-app"] + repo_names = ["bu1-example-app"] + terraform_service_accounts = values(module.infra_pipelines[0].terraform_service_accounts) } module "app_infra_cloudbuild_project" { @@ -31,6 +32,11 @@ module "app_infra_cloudbuild_project" { project_deletion_policy = var.project_deletion_policy + vpc_service_control_attach_enabled = local.enforce_vpcsc ? "true" : "false" + vpc_service_control_attach_dry_run = !local.enforce_vpcsc ? "true" : "false" + vpc_service_control_perimeter_name = "accessPolicies/${local.access_context_manager_policy_id}/servicePerimeters/${local.perimeter_name}" + vpc_service_control_sleep_duration = "60s" + activate_apis = [ "cloudbuild.googleapis.com", "sourcerepo.googleapis.com", diff --git a/4-projects/business_unit_1/shared/outputs.tf b/4-projects/business_unit_1/shared/outputs.tf index 5c3a84874..c3abff1a7 100644 --- a/4-projects/business_unit_1/shared/outputs.tf +++ b/4-projects/business_unit_1/shared/outputs.tf @@ -23,6 +23,10 @@ output "cloudbuild_project_id" { value = try(module.app_infra_cloudbuild_project[0].project_id, "") } +output "cloudbuild_project_number" { + value = module.app_infra_cloudbuild_project[0].project_number +} + output "terraform_service_accounts" { description = "APP Infra Pipeline Terraform Accounts." value = try(module.infra_pipelines[0].terraform_service_accounts, {}) diff --git a/4-projects/business_unit_1/shared/remote.tf b/4-projects/business_unit_1/shared/remote.tf index 2597f19ba..fe0067401 100644 --- a/4-projects/business_unit_1/shared/remote.tf +++ b/4-projects/business_unit_1/shared/remote.tf @@ -27,6 +27,9 @@ locals { cloud_build_private_worker_pool_id = try(data.terraform_remote_state.bootstrap.outputs.cloud_build_private_worker_pool_id, "") cloud_builder_artifact_repo = try(data.terraform_remote_state.bootstrap.outputs.cloud_builder_artifact_repo, "") enable_cloudbuild_deploy = local.cloud_builder_artifact_repo != "" + perimeter_name = data.terraform_remote_state.org.outputs.service_perimeter_name + enforce_vpcsc = data.terraform_remote_state.org.outputs.enforce_vpcsc + access_context_manager_policy_id = data.terraform_remote_state.org.outputs.access_context_manager_policy_id } data "terraform_remote_state" "bootstrap" { diff --git a/4-projects/modules/base_env/example_floating_project.tf b/4-projects/modules/base_env/example_floating_project.tf index e8bbe7406..db877762c 100644 --- a/4-projects/modules/base_env/example_floating_project.tf +++ b/4-projects/modules/base_env/example_floating_project.tf @@ -26,6 +26,11 @@ module "floating_project" { project_deletion_policy = var.project_deletion_policy + vpc_service_control_attach_enabled = local.enforce_vpcsc ? "true" : "false" + vpc_service_control_attach_dry_run = !local.enforce_vpcsc ? "true" : "false" + vpc_service_control_perimeter_name = "accessPolicies/${local.access_context_manager_policy_id}/servicePerimeters/${local.perimeter_name}" + vpc_service_control_sleep_duration = "60s" + # Metadata project_suffix = "sample-floating" application_name = "${var.business_code}-sample-application" diff --git a/4-projects/modules/base_env/example_peering_project.tf b/4-projects/modules/base_env/example_peering_project.tf index 6a2a36f7c..7f40781af 100644 --- a/4-projects/modules/base_env/example_peering_project.tf +++ b/4-projects/modules/base_env/example_peering_project.tf @@ -61,6 +61,11 @@ module "peering_project" { ] } + vpc_service_control_attach_enabled = local.enforce_vpcsc ? "true" : "false" + vpc_service_control_attach_dry_run = !local.enforce_vpcsc ? "true" : "false" + vpc_service_control_perimeter_name = "accessPolicies/${local.access_context_manager_policy_id}/servicePerimeters/${local.perimeter_name}" + vpc_service_control_sleep_duration = "60s" + activate_apis = [ "dns.googleapis.com" ] diff --git a/4-projects/modules/base_env/example_shared_vpc_project.tf b/4-projects/modules/base_env/example_shared_vpc_project.tf index 0f0b52784..139d9c9f5 100644 --- a/4-projects/modules/base_env/example_shared_vpc_project.tf +++ b/4-projects/modules/base_env/example_shared_vpc_project.tf @@ -39,7 +39,8 @@ module "shared_vpc_project" { ] } - activate_apis = ["accesscontextmanager.googleapis.com"] + activate_apis = ["accesscontextmanager.googleapis.com"] + vpc_service_control_attach_enabled = local.enforce_vpcsc ? "true" : "false" vpc_service_control_attach_dry_run = !local.enforce_vpcsc ? "true" : "false" vpc_service_control_perimeter_name = "accessPolicies/${local.access_context_manager_policy_id}/servicePerimeters/${local.perimeter_name}" diff --git a/4-projects/modules/infra_pipelines/README.md b/4-projects/modules/infra_pipelines/README.md index 22f84a7a6..dd2988283 100644 --- a/4-projects/modules/infra_pipelines/README.md +++ b/4-projects/modules/infra_pipelines/README.md @@ -13,8 +13,6 @@ | private\_worker\_pool\_id | ID of the Cloud Build private worker pool. | `string` | n/a | yes | | remote\_tfstate\_bucket | Bucket with remote state data to be used by the pipeline. | `string` | n/a | yes | | terraform\_docker\_tag\_version | TAG version of the terraform docker image. | `string` | `"v1"` | no | -| vpc\_service\_control\_attach\_dry\_run | Whether the project will be attached to a VPC Service Control Perimeter with an explicit dry run spec flag, which may use different values for the dry run perimeter compared to the ENFORCED perimeter. | `bool` | `false` | no | -| vpc\_service\_control\_attach\_enabled | Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. | `bool` | `false` | no | ## Outputs diff --git a/4-projects/modules/infra_pipelines/variables.tf b/4-projects/modules/infra_pipelines/variables.tf index c9284d665..63492db1e 100644 --- a/4-projects/modules/infra_pipelines/variables.tf +++ b/4-projects/modules/infra_pipelines/variables.tf @@ -66,16 +66,3 @@ variable "bucket_prefix" { type = string default = "bkt" } - -variable "vpc_service_control_attach_enabled" { - description = "Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE." - type = bool - default = false -} - - -variable "vpc_service_control_attach_dry_run" { - description = "Whether the project will be attached to a VPC Service Control Perimeter with an explicit dry run spec flag, which may use different values for the dry run perimeter compared to the ENFORCED perimeter." - type = bool - default = false -} From 03fc14cb8129b5599223c4fa5cc2329ba1c4a5f0 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 4 Aug 2025 19:52:06 -0300 Subject: [PATCH 025/114] add roles/iam.serviceAccountAdmin proj SA folder level --- 0-bootstrap/sa.tf | 1 + 1 file changed, 1 insertion(+) diff --git a/0-bootstrap/sa.tf b/0-bootstrap/sa.tf index ac849dafe..f7c0f3ac5 100644 --- a/0-bootstrap/sa.tf +++ b/0-bootstrap/sa.tf @@ -93,6 +93,7 @@ locals { "roles/artifactregistry.admin", "roles/compute.networkAdmin", "roles/compute.xpnAdmin", + "roles/iam.serviceAccountAdmin" ], } From 5ac971b85f2286575ec87c1ed955edc77feca515 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 5 Aug 2025 13:35:00 -0300 Subject: [PATCH 026/114] upd README with required directional rules instructions to add --- 4-projects/README.md | 128 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/4-projects/README.md b/4-projects/README.md index 96464bf9f..e2f8e7b32 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -220,13 +220,75 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' git push origin nonproduction ``` -1. Before executing the next step, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +2. Use `terraform output` to get the APP Infra Pipeline Terraform service account. + + ```bash + export terraform_service_accounts=$(terraform -chdir="business_unit_1/shared/" output -json terraform_service_accounts | jq -r 'to_entries[0].value') + echo $terraform_service_accounts + ``` + +3. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: + + ``` + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + "logging.googleapis.com" = { + methods = ["*"] + } + "iamcredentials.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ``` + +4. Before executing the next step, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -1. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. +5. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. ### Deploying with Jenkins @@ -402,6 +464,68 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' cd ../ ``` +1. Use `terraform output` to get the APP Infra Pipeline Terraform service account. + + ```bash + export terraform_service_accounts=$(terraform -chdir="business_unit_1/shared/" output -json terraform_service_accounts | jq -r 'to_entries[0].value') + echo $terraform_service_accounts + ``` + +3. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: + + ``` + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + "logging.googleapis.com" = { + methods = ["*"] + } + "iamcredentials.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ``` + If you received any errors or made any changes to the Terraform config or any `.tfvars`, you must re-run `./tf-wrapper.sh plan ` before run `./tf-wrapper.sh apply `. Before executing the next stages, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. From 1a09eea35c020e8dae3df0b7b03bf9c46a9e5efe Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 5 Aug 2025 14:13:04 -0300 Subject: [PATCH 027/114] updt README with add direcional rule instructions --- 1-org/README.md | 64 +++++++++++++++++++++++++--- 1-org/envs/shared/service_control.tf | 27 ++++++++++-- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/1-org/README.md b/1-org/README.md index 1c9ac202b..e9484bbdf 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -173,7 +173,34 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f if [ ! -z "${ACCESS_CONTEXT_MANAGER_ID}" ]; then sed -i'' -e "s=//create_access_context_manager_access_policy=create_access_context_manager_access_policy=" ./envs/shared/terraform.tfvars; fi ``` -1. Run `terraform init` in `/envs/shared` to generate the outputs used in other steps. +2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: + + ``` + { + from = { + identities = [ + "user:YOUR-USER-EMAIL@example.com", + ] + sources = { + resources = [ + "projects/${local.seed_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ``` + +3. Run `terraform init` in `/envs/shared` to generate the outputs used in other steps. ```bash cd envs/shared @@ -181,14 +208,14 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f cd ../.. ``` -1. Commit changes. +4. Commit changes. ```bash git add . git commit -m 'Initialize org repo' ``` -1. Push your plan branch to trigger a plan for all environments. Because the +5. Push your plan branch to trigger a plan for all environments. Because the _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing your _plan_ branch triggers _terraform plan_ but not _terraform apply_. Review the plan output in your Cloud Build project. @@ -196,7 +223,7 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f git push --set-upstream origin plan ``` -1. Merge changes to the production branch. Because the _production_ branch is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +6. Merge changes to the production branch. Because the _production_ branch is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project. ```bash @@ -204,7 +231,7 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f git push origin production ``` -1. Proceed to the [2-environments](../2-environments/README.md) step. +7. Proceed to the [2-environments](../2-environments/README.md) step. **Troubleshooting:** If you received a `PERMISSION_DENIED` error while running the `gcloud access-context-manager` or the `gcloud scc notifications` commands, you can append the following to run the command as the Terraform service account: @@ -270,6 +297,33 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./envs/shared/terraform.tfvars ``` +2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: + + ``` + { + from = { + identities = [ + "user:YOUR-USER-EMAIL@example.com", + ] + sources = { + resources = [ + "projects/${local.seed_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ``` + 1. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 1f0cc1764..e07268f9e 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -158,7 +158,7 @@ locals { }) : tostring(v) ] - projects = distinct(concat([ + projects = var.enable_hub_and_spoke ? (concat([ local.seed_project_number, module.org_audit_logs.project_number, module.org_billing_export.project_number, @@ -166,10 +166,31 @@ locals { module.org_secrets.project_number, module.interconnect.project_number, module.scc_notifications.project_number, + module.network_hub.project_number, ], local.shared_vpc_projects_numbers - )) + )) : (concat([ + local.seed_project_number, + module.org_audit_logs.project_number, + module.org_billing_export.project_number, + module.common_kms.project_number, + module.org_secrets.project_number, + module.interconnect.project_number, + module.scc_notifications.project_number, + ], local.shared_vpc_projects_numbers)) - project_keys = [ + project_keys = var.enable_hub_and_spoke ? [ + "prj-org-seed", + "prj-org-audit", + "prj-org-billing", + "prj-org-kms", + "prj-org-secrets", + "prj-org-interconnect", + "prj-org-scc", + "prj-net-hub", + "prj-net-p-svpc", + "prj-net-d-svpc", + "prj-net-n-svpc", + ] : [ "prj-org-seed", "prj-org-audit", "prj-org-billing", From 244f850ec779965db6933114778011a7fa04c2a0 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 6 Aug 2025 10:22:47 -0300 Subject: [PATCH 028/114] Initialize policy library repo --- 0-bootstrap/README.md | 4 +- 0-bootstrap/backend.tf | 22 ++++ 0-bootstrap/bootstrap.json | 1 + 0-bootstrap/bootstrap.tfplan | Bin 0 -> 281042 bytes 0-bootstrap/terraform.example.tfvars | 171 --------------------------- 5 files changed, 25 insertions(+), 173 deletions(-) create mode 100644 0-bootstrap/backend.tf create mode 100644 0-bootstrap/bootstrap.json create mode 100644 0-bootstrap/bootstrap.tfplan delete mode 100644 0-bootstrap/terraform.example.tfvars diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md index 87baa2a0b..02f1e2958 100644 --- a/0-bootstrap/README.md +++ b/0-bootstrap/README.md @@ -224,7 +224,7 @@ The following steps introduce the steps to deploy with Cloud Build Alternatively 1. Use the helper script [validate-requirements.sh](../scripts/validate-requirements.sh) to validate your environment: ```bash - ../scripts/validate-requirements.sh -o -b -u + ../scripts/validate-requirements.sh -o 1055058813388 -b 01AAD1-616217-97513A -u mariamartins@clsecteam.com ``` **Note:** The script is not able to validate if the user is in a Cloud Identity or Google Workspace group with the required roles. @@ -241,7 +241,7 @@ The following steps introduce the steps to deploy with Cloud Build Alternatively 1. Run the following commands and check for violations: ```bash - export VET_PROJECT_ID=A-VALID-PROJECT-ID + export VET_PROJECT_ID=deployer-foundation terraform show -json bootstrap.tfplan > bootstrap.json gcloud beta terraform vet bootstrap.json --policy-library="../policy-library" --project ${VET_PROJECT_ID} ``` diff --git a/0-bootstrap/backend.tf b/0-bootstrap/backend.tf new file mode 100644 index 000000000..d68aaa77f --- /dev/null +++ b/0-bootstrap/backend.tf @@ -0,0 +1,22 @@ +/** + * Copyright 2021 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. + */ + +terraform { + backend "gcs" { + bucket = "bkt-prj-b-seed-tfstate-9e2b" + prefix = "terraform/bootstrap/state" + } +} diff --git a/0-bootstrap/bootstrap.json b/0-bootstrap/bootstrap.json new file mode 100644 index 000000000..96c0e258b --- /dev/null +++ b/0-bootstrap/bootstrap.json @@ -0,0 +1 @@ +{"format_version":"1.2","terraform_version":"1.5.7","variables":{"attribute_condition":{"value":null},"billing_account":{"value":"01AAD1-616217-97513A"},"bucket_force_destroy":{"value":false},"bucket_prefix":{"value":"bkt"},"bucket_tfstate_kms_force_destroy":{"value":false},"default_region":{"value":"us-central1"},"default_region_2":{"value":"us-west1"},"default_region_gcs":{"value":"US"},"default_region_kms":{"value":"us"},"folder_deletion_protection":{"value":"true"},"folder_prefix":{"value":"fldr"},"groups":{"value":{"required_groups":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"}}},"initial_group_config":{"value":"WITH_INITIAL_OWNER"},"org_id":{"value":"1055058813388"},"org_policy_admin_role":{"value":false},"parent_folder":{"value":"49822046027"},"project_deletion_policy":{"value":"PREVENT"},"project_prefix":{"value":"prj"},"workflow_deletion_protection":{"value":true}},"planned_values":{"outputs":{"bootstrap_step_terraform_service_account_email":{"sensitive":false},"cloud_build_peered_network_id":{"sensitive":false},"cloud_build_private_worker_pool_id":{"sensitive":false},"cloud_build_worker_peered_ip_range":{"sensitive":false,"type":"string","value":"192.168.0.0/24"},"cloud_build_worker_range_id":{"sensitive":false},"cloud_builder_artifact_repo":{"sensitive":false},"cloudbuild_project_id":{"sensitive":false},"cloudbuild_project_number":{"sensitive":false},"common_config":{"sensitive":false},"csr_repos":{"sensitive":false},"environment_step_terraform_service_account_email":{"sensitive":false},"gcs_bucket_cloudbuild_artifacts":{"sensitive":false},"gcs_bucket_cloudbuild_logs":{"sensitive":false},"gcs_bucket_tfstate":{"sensitive":false},"networks_step_terraform_service_account_email":{"sensitive":false},"optional_groups":{"sensitive":false,"type":["map","string"],"value":{"gcp_global_secrets_admin":"","gcp_kms_admin":"","gcp_network_viewer":"","gcp_scc_admin":"","gcp_security_reviewer":""}},"organization_step_terraform_service_account_email":{"sensitive":false},"parent_id":{"sensitive":false,"type":"string","value":"folder-49822046027"},"projects_gcs_bucket_tfstate":{"sensitive":false},"projects_step_terraform_service_account_email":{"sensitive":false},"required_groups":{"sensitive":false,"type":["map","string"],"value":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"}},"seed_project_id":{"sensitive":false},"seed_project_number":{"sensitive":false}},"root_module":{"resources":[{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"data.google_project.seed_project","mode":"data","type":"google_project","name":"seed_project","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"bootstrap\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"env\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"net\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"org\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"proj\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_account_sink","mode":"managed","type":"google_billing_account_iam_member","name":"billing_account_sink","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/logging.configWriter"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_folder.bootstrap","mode":"managed","type":"google_folder","name":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"deletion_protection":true,"display_name":"fldr-bootstrap","parent":"folders/49822046027","tags":null,"timeouts":null},"sensitive_values":{}},{"address":"google_project_service_identity.workflows_identity","mode":"managed","type":"google_project_service_identity","name":"workflows_identity","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"service":"workflows.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"bootstrap\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-bootstrap","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Bootstrap SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"env\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-env","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Environment SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"net\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-net","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Network SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"org\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-org","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Organization SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"proj\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-proj","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Projects SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_sourcerepo_repository_iam_member.member[\"bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"env\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"net\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"org\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"proj\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":2,"values":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"sensitive_values":{}},{"address":"time_sleep.cloud_builder","mode":"managed","type":"time_sleep","name":"cloud_builder","provider_name":"registry.terraform.io/hashicorp/time","schema_version":0,"values":{"create_duration":"30s","destroy_duration":null,"triggers":null},"sensitive_values":{}}],"child_modules":[{"resources":[{"address":"module.bootstrap_csr_repo.null_resource.run_command[0]","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"create_cmd_entrypoint":"./scripts/push-to-repo.sh","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"ad3634e17109216cf99cbd7242475359"}},"sensitive_values":{"triggers":{}}},{"address":"module.bootstrap_csr_repo.null_resource.run_destroy_command[0]","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin"}},"sensitive_values":{"triggers":{}}}],"address":"module.bootstrap_csr_repo"},{"resources":[{"address":"module.bootstrap_projects_remove_editor[\"cicd\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"members":null,"role":"roles/editor"},"sensitive_values":{"condition":[]}}],"address":"module.bootstrap_projects_remove_editor[\"cicd\"]"},{"resources":[{"address":"module.bootstrap_projects_remove_editor[\"seed\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"members":null,"role":"roles/editor"},"sensitive_values":{"condition":[]}}],"address":"module.bootstrap_projects_remove_editor[\"seed\"]"},{"resources":[{"address":"module.build_terraform_image.null_resource.module_depends_on[0]","mode":"managed","type":"null_resource","name":"module_depends_on","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"value":"1"}},"sensitive_values":{"triggers":{}}},{"address":"module.build_terraform_image.null_resource.run_command[0]","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"create_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"7f22bf39aaf5ce5980111c3587bef5b5","terraform_version":"1.5.7"}},"sensitive_values":{"triggers":{}}},{"address":"module.build_terraform_image.null_resource.run_destroy_command[0]","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","terraform_version":"1.5.7"}},"sensitive_values":{"triggers":{}}}],"address":"module.build_terraform_image"},{"resources":[{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/artifactregistry.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/artifactregistry.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.builds.editor\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.builds.editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.workerPoolOwner\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.workerPoolOwner","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolOwner"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudscheduler.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudscheduler.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudscheduler.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/compute.networkAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/compute.networkAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/dns.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/dns.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.workloadIdentityPoolAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.workloadIdentityPoolAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.workloadIdentityPoolAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/source.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/source.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/source.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/workflows.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/workflows.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/workflows.admin"},"sensitive_values":{"condition":[]}}],"address":"module.cicd_project_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.gcp_projects_state_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.gcp_projects_state_bucket"},{"resources":[{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/assuredworkloads.admin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/assuredworkloads.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/assuredworkloads.admin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"env\"]"},{"resources":[{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/compute.xpnAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/compute.xpnAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"net\"]"},{"resources":[{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/cloudasset.owner\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudasset.owner","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/cloudasset.owner"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/essentialcontacts.admin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/essentialcontacts.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/essentialcontacts.admin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/logging.configWriter\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/logging.configWriter","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/logging.configWriter"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/orgpolicy.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/orgpolicy.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/orgpolicy.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationViewer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationViewer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationViewer"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.notificationConfigEditor\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.notificationConfigEditor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.notificationConfigEditor"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.sourcesEditor\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.sourcesEditor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.sourcesEditor"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"org\"]"},{"resources":[{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/cloudkms.admin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/cloudkms.admin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"proj\"]"},{"resources":[{"address":"module.parent_iam_member[\"bootstrap\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.parent_iam_member[\"env\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"env\"]"},{"resources":[{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityPolicyAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityPolicyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityPolicyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityResourceAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityResourceAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityResourceAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.securityAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.securityAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.securityAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/dns.admin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/dns.admin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderViewer\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderViewer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderViewer"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"net\"]"},{"resources":[{"address":"module.parent_iam_member[\"org\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"org\"]"},{"resources":[{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/artifactregistry.admin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/artifactregistry.admin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.xpnAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.xpnAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/iam.serviceAccountAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/iam.serviceAccountAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"proj\"]"},{"resources":[{"address":"module.seed_bootstrap.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.google_folder_iam_binding.project_creator[0]","mode":"managed","type":"google_folder_iam_binding","name":"project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.projectCreator"},"sensitive_values":{"condition":[],"members":[]}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_service_account_user[0]","mode":"managed","type":"google_folder_iam_member","name":"org_admin_service_account_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_serviceusage_consumer[0]","mode":"managed","type":"google_folder_iam_member","name":"org_admin_serviceusage_consumer","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_folder_iam_member.tmp_project_creator[0]","mode":"managed","type":"google_folder_iam_member","name":"tmp_project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/resourcemanager.projectCreator"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_organization_iam_binding.billing_creator","mode":"managed","type":"google_organization_iam_binding","name":"billing_creator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"members":["group:billing_admin_duda_foundation@clsecteam.com"],"org_id":"1055058813388","role":"roles/billing.creator"},"sensitive_values":{"condition":[],"members":[false]}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/billing.user\"]","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/billing.user","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_billing_admin","mode":"managed","type":"google_organization_iam_member","name":"org_billing_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:billing_admin_duda_foundation@clsecteam.com","org_id":"1055058813388","role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_storage_bucket.org_terraform_state","mode":"managed","type":"google_storage_bucket","name":"org_terraform_state","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"requester_pays":null,"retention_policy":[],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[],"terraform_labels":{},"versioning":[{}],"website":[]}},{"address":"module.seed_bootstrap.google_storage_bucket_iam_member.orgadmins_state_iam[0]","mode":"managed","type":"google_storage_bucket_iam_member","name":"orgadmins_state_iam","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.random_id.suffix","mode":"managed","type":"random_id","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":0,"values":{"byte_length":2,"keepers":null,"prefix":null},"sensitive_values":{}}],"address":"module.seed_bootstrap","child_modules":[{"address":"module.seed_bootstrap.module.seed_project","child_modules":[{"resources":[{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"name":"prj-b-seed","tags":null,"terraform_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"sensitive_values":{"effective_labels":{},"labels":{},"terraform_labels":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"sensitive_values":{"service_accounts":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_resource_manager_lien.lien[0]","mode":"managed","type":"google_resource_manager_lien","name":"lien","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"origin":"project-factory","reason":"Project Factory lien","restrictions":["resourcemanager.projects.delete"],"timeouts":null},"sensitive_values":{"restrictions":[false]}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":0,"values":{"byte_length":2,"keepers":null,"prefix":null},"sensitive_values":{}}],"address":"module.seed_bootstrap.module.seed_project.module.project-factory","child_modules":[{"resources":[{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"accesscontextmanager.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"accesscontextmanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"accesscontextmanager.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"assuredworkloads.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"assuredworkloads.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"assuredworkloads.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudasset.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudasset.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudasset.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudkms.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudkms.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudkms.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"essentialcontacts.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"essentialcontacts.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"essentialcontacts.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iamcredentials.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"iamcredentials.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iamcredentials.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"monitoring.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"monitoring.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"monitoring.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"pubsub.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"pubsub.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"pubsub.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"securitycenter.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"securitycenter.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"securitycenter.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"sensitive_values":{}}],"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services"}]}]},{"resources":[{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key[0]","mode":"managed","type":"google_kms_crypto_key","name":"key","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"effective_labels":{"goog-terraform-provisioned":"true"},"import_only":false,"labels":null,"name":"prj-key","purpose":"ENCRYPT_DECRYPT","rotation_period":"7776000s","skip_initial_version_creation":false,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"version_template":[{"algorithm":"GOOGLE_SYMMETRIC_ENCRYPTION","protection_level":"SOFTWARE"}]},"sensitive_values":{"effective_labels":{},"primary":[],"terraform_labels":{},"version_template":[{}]}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.decrypters[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudkms.cryptoKeyDecrypter"},"sensitive_values":{"condition":[],"members":[]}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.encrypters[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudkms.cryptoKeyEncrypter"},"sensitive_values":{"condition":[],"members":[]}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"location":"us-central1","name":"prj-keyring","timeouts":null},"sensitive_values":{}}],"address":"module.seed_bootstrap.module.kms[0]"},{"resources":[{"address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage.google_project_organization_policy.project_policy_boolean[0]","mode":"managed","type":"google_project_organization_policy","name":"project_policy_boolean","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"boolean_policy":[{"enforced":false}],"constraint":"constraints/iam.disableCrossProjectServiceAccountUsage","list_policy":[],"restore_policy":[],"timeouts":null},"sensitive_values":{"boolean_policy":[{}],"list_policy":[],"restore_policy":[]}}],"address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage"}]},{"resources":[{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudkms.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudkms.admin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"sensitive_values":{"condition":[]}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"env\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"env\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"net\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"net\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"org\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"org\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"proj\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"proj\"]"},{"resources":[{"address":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","mode":"managed","type":"google_artifact_registry_repository","name":"tf-image-repo","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"cleanup_policies":[],"cleanup_policy_dry_run":null,"description":"Docker repository for Terraform runner images used by Cloud Build. Managed by Terraform.","docker_config":[],"effective_labels":{"goog-terraform-provisioned":"true"},"format":"DOCKER","kms_key_name":null,"labels":null,"location":"us-central1","maven_config":[],"mode":"STANDARD_REPOSITORY","remote_repository_config":[],"repository_id":"tf-runners","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"virtual_repository_config":[]},"sensitive_values":{"cleanup_policies":[],"docker_config":[],"effective_labels":{},"maven_config":[],"remote_repository_config":[],"terraform_labels":{},"virtual_repository_config":[],"vulnerability_scanning_config":[]}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.push_images","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"push_images","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.writer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.workflow_list","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"workflow_list","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_cloud_scheduler_job.trigger_workflow","mode":"managed","type":"google_cloud_scheduler_job","name":"trigger_workflow","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"app_engine_http_target":[],"attempt_deadline":null,"description":"Trigger workflow for TF Runner builds. Managed by Terraform.","http_target":[{"body":null,"headers":null,"http_method":"POST","oauth_token":[{"scope":"https://www.googleapis.com/auth/cloud-platform"}],"oidc_token":[]}],"name":"trigger-terraform-runner-workflow","pubsub_target":[],"region":"us-central1","retry_config":[],"schedule":"0 8 * * *","time_zone":"Etc/UTC","timeouts":null},"sensitive_values":{"app_engine_http_target":[],"http_target":[{"oauth_token":[{}],"oidc_token":[]}],"pubsub_target":[],"retry_config":[]}},{"address":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","mode":"managed","type":"google_cloudbuild_trigger","name":"build_trigger","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"options":[{"disk_size_gb":null,"dynamic_substitutions":null,"env":null,"log_streaming_option":null,"logging":null,"machine_type":null,"requested_verify_option":null,"secret_env":null,"source_provenance_hash":null,"substitution_option":null,"volumes":[]}],"queue_ttl":null,"secret":[],"source":[],"step":[{"allow_exit_codes":null,"allow_failure":null,"dir":null,"entrypoint":null,"env":null,"id":null,"name":"gcr.io/cloud-builders/docker","script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null},{"allow_exit_codes":null,"allow_failure":null,"args":["version"],"dir":null,"entrypoint":null,"env":null,"id":null,"script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null}],"substitutions":null,"tags":null,"timeout":"1200s"}],"description":"Builds a Terraform runner image. Managed by Terraform.","disabled":null,"filename":null,"filter":null,"git_file_source":[],"github":[],"ignored_files":null,"include_build_logs":null,"included_files":null,"location":"us-central1","name":"tf-cloud-builder-build","pubsub_config":[],"repository_event_config":[],"source_to_build":[{"bitbucket_server_config":null,"github_enterprise_config":null,"ref":"refs/heads/main","repo_type":"CLOUD_SOURCE_REPOSITORIES","repository":null}],"substitutions":{"_TERRAFORM_FULL_VERSION":"1.5.7","_TERRAFORM_MAJOR_VERSION":"1","_TERRAFORM_MINOR_VERSION":"1.5"},"tags":null,"timeouts":null,"trigger_template":[],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"images":[],"options":[{"volumes":[]}],"secret":[],"source":[],"step":[{"args":[],"volumes":[]},{"args":[false],"volumes":[]}]}],"git_file_source":[],"github":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[{}],"substitutions":{},"trigger_template":[],"webhook_config":[]}},{"address":"module.tf_cloud_builder.google_project_iam_member.invoke_workflow_scheduler","mode":"managed","type":"google_project_iam_member","name":"invoke_workflow_scheduler","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/workflows.invoker"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_project_iam_member.logs_writer","mode":"managed","type":"google_project_iam_member","name":"logs_writer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_project_iam_member.trigger_builds","mode":"managed","type":"google_project_iam_member","name":"trigger_builds","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_service_account.cb_sa[0]","mode":"managed","type":"google_service_account","name":"cb_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"tf-cb-builder-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for Terraform builder build trigger. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"module.tf_cloud_builder.google_service_account.workflow_sa[0]","mode":"managed","type":"google_service_account","name":"workflow_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"terraform-runner-workflow-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for TF Builder Workflow. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"module.tf_cloud_builder.google_service_account_iam_member.use_cb_sa","mode":"managed","type":"google_service_account_iam_member","name":"use_cb_sa","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_storage_bucket_iam_member.member","mode":"managed","type":"google_storage_bucket_iam_member","name":"member","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_workflows_workflow.builder","mode":"managed","type":"google_workflows_workflow","name":"builder","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"call_log_level":null,"crypto_key_name":null,"deletion_protection":true,"description":"Workflow for triggering TF Runner builds. Managed by Terraform.","effective_labels":{"goog-terraform-provisioned":"true"},"execution_history_level":null,"labels":null,"name":"terraform-runner-workflow","region":"us-central1","tags":null,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"user_env_vars":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}}],"address":"module.tf_cloud_builder","child_modules":[{"resources":[{"address":"module.tf_cloud_builder.module.bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_cloud_builder.module.bucket"}]},{"resources":[{"address":"module.tf_private_pool.google_cloudbuild_worker_pool.private_pool","mode":"managed","type":"google_cloudbuild_worker_pool","name":"private_pool","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"annotations":null,"display_name":null,"location":"us-central1","network_config":[{"peered_network_ip_range":null}],"private_service_connect":[],"timeouts":null,"worker_config":[{"disk_size_gb":100,"machine_type":"e2-medium","no_external_ip":true}]},"sensitive_values":{"effective_annotations":{},"network_config":[{}],"private_service_connect":[],"worker_config":[{}]}},{"address":"module.tf_private_pool.google_compute_address.cloud_build_nat","mode":"managed","type":"google_compute_address","name":"cloud_build_nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"address_type":"EXTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"ipv6_endpoint_type":null,"labels":null,"name":"cloud-build-nat","network":null,"network_tier":"PREMIUM","region":"us-central1","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{},"users":[]}},{"address":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","mode":"managed","type":"google_compute_global_address","name":"worker_pool_range","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"address":"192.168.0.0","address_type":"INTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"labels":null,"name":"ga-b-cbpools-worker-pool-range","prefix_length":24,"purpose":"VPC_PEERING","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}},{"address":"module.tf_private_pool.google_compute_instance.vm-proxy","mode":"managed","type":"google_compute_instance","name":"vm-proxy","provider_name":"registry.terraform.io/hashicorp/google","schema_version":6,"values":{"advanced_machine_features":[],"allow_stopping_for_update":null,"attached_disk":[],"boot_disk":[{"auto_delete":true,"disk_encryption_key_raw":null,"disk_encryption_key_rsa":null,"disk_encryption_service_account":null,"force_attach":null,"initialize_params":[{"enable_confidential_compute":null,"image":"debian-cloud/debian-12","resource_manager_tags":null,"source_image_encryption_key":[],"source_snapshot_encryption_key":[],"storage_pool":null}],"interface":null,"mode":"READ_WRITE"}],"can_ip_forward":true,"deletion_protection":false,"description":null,"desired_status":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_display":null,"hostname":null,"instance_encryption_key":[],"key_revocation_action_type":null,"labels":null,"machine_type":"e2-medium","metadata":null,"metadata_startup_script":"sysctl -w net.ipv4.ip_forward=1 \u0026\u0026 iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE","name":"cloud-build-nat-vm","network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[],"nic_type":null,"queue_count":null,"subnetwork":"sb-b-cbpools-us-central1"}],"network_performance_config":[],"params":[],"resource_policies":null,"scratch_disk":[],"service_account":[{"scopes":["https://www.googleapis.com/auth/cloud-platform"]}],"shielded_instance_config":[],"tags":["direct-gateway-access","nat-gateway"],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"zone":"us-central1-a"},"sensitive_values":{"advanced_machine_features":[],"attached_disk":[],"boot_disk":[{"guest_os_features":[],"initialize_params":[{"labels":{},"resource_policies":[],"source_image_encryption_key":[],"source_snapshot_encryption_key":[]}]}],"confidential_instance_config":[],"effective_labels":{},"guest_accelerator":[],"instance_encryption_key":[],"network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[]}],"network_performance_config":[],"params":[],"reservation_affinity":[],"scheduling":[],"scratch_disk":[],"service_account":[{"scopes":[false]}],"shielded_instance_config":[],"tags":[false,false],"terraform_labels":{}}},{"address":"module.tf_private_pool.google_compute_network_peering_routes_config.peering_routes[0]","mode":"managed","type":"google_compute_network_peering_routes_config","name":"peering_routes","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"export_custom_routes":true,"import_custom_routes":true,"timeouts":null},"sensitive_values":{}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway","mode":"managed","type":"google_compute_route","name":"direct-to-gateway","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"0.0.0.0/1","name":"direct-to-gateway-range1","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway2","mode":"managed","type":"google_compute_route","name":"direct-to-gateway2","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"128.0.0.0/1","name":"direct-to-gateway-range2","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_route.through-nat","mode":"managed","type":"google_compute_route","name":"through-nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"0.0.0.0/1","name":"through-nat-range1","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_route.through-nat2","mode":"managed","type":"google_compute_route","name":"through-nat2","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"128.0.0.0/1","name":"through-nat-range2","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_router.cb-router","mode":"managed","type":"google_compute_router","name":"cb-router","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"bgp":[],"description":null,"encrypted_interconnect_router":null,"md5_authentication_keys":[],"name":"cb-cloud-router","region":"us-central1","timeouts":null},"sensitive_values":{"bgp":[],"md5_authentication_keys":[]}},{"address":"module.tf_private_pool.google_compute_router_nat.cb-nat","mode":"managed","type":"google_compute_router_nat","name":"cb-nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"icmp_idle_timeout_sec":30,"initial_nat_ips":null,"log_config":[{"enable":true,"filter":"ALL"}],"max_ports_per_vm":null,"name":"cb-cloud-nat","nat64_subnetwork":[],"nat_ip_allocate_option":"AUTO_ONLY","region":"us-central1","router":"cb-cloud-router","rules":[],"source_subnetwork_ip_ranges_to_nat":"ALL_SUBNETWORKS_ALL_IP_RANGES","source_subnetwork_ip_ranges_to_nat64":null,"subnetwork":[],"tcp_established_idle_timeout_sec":1200,"tcp_time_wait_timeout_sec":120,"tcp_transitory_idle_timeout_sec":30,"timeouts":null,"type":"PUBLIC","udp_idle_timeout_sec":30},"sensitive_values":{"drain_nat_ips":[],"endpoint_types":[],"log_config":[{}],"nat64_subnetwork":[],"nat_ips":[],"rules":[],"subnetwork":[]}},{"address":"module.tf_private_pool.google_dns_policy.default_policy[0]","mode":"managed","type":"google_dns_policy","name":"default_policy","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"alternative_name_server_config":[],"description":"Managed by Terraform","enable_inbound_forwarding":true,"enable_logging":true,"name":"dp-b-cbpools-default-policy","networks":[{}],"timeouts":null},"sensitive_values":{"alternative_name_server_config":[],"dns64_config":[],"networks":[{}]}},{"address":"module.tf_private_pool.google_service_networking_connection.worker_pool_conn[0]","mode":"managed","type":"google_service_networking_connection","name":"worker_pool_conn","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"deletion_policy":null,"reserved_peering_ranges":["ga-b-cbpools-worker-pool-range"],"service":"servicenetworking.googleapis.com","timeouts":null,"update_on_creation_fail":null},"sensitive_values":{"reserved_peering_ranges":[false]}},{"address":"module.tf_private_pool.random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":2,"values":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"sensitive_values":{}}],"address":"module.tf_private_pool","child_modules":[{"address":"module.tf_private_pool.module.peered_network[0]","child_modules":[{"resources":[{"address":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","mode":"managed","type":"google_compute_network","name":"network","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"auto_create_subnetworks":false,"delete_default_routes_on_create":true,"description":"","enable_ula_internal_ipv6":false,"mtu":0,"name":"vpc-b-cbpools","network_firewall_policy_enforcement_order":"AFTER_CLASSIC_FIREWALL","network_profile":null,"params":[],"routing_mode":"GLOBAL","timeouts":null},"sensitive_values":{"params":[]}}],"address":"module.tf_private_pool.module.peered_network[0].module.vpc"},{"resources":[{"address":"module.tf_private_pool.module.peered_network[0].module.subnets.google_compute_subnetwork.subnetwork[\"us-central1/sb-b-cbpools-us-central1\"]","mode":"managed","type":"google_compute_subnetwork","name":"subnetwork","index":"us-central1/sb-b-cbpools-us-central1","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":"Peered subnet for Cloud Build private pool","ip_cidr_range":"10.3.0.0/24","ip_collection":null,"ipv6_access_type":null,"log_config":[{"aggregation_interval":"INTERVAL_5_SEC","filter_expr":"true","flow_sampling":0.5,"metadata":"INCLUDE_ALL_METADATA","metadata_fields":null}],"name":"sb-b-cbpools-us-central1","network":"vpc-b-cbpools","params":[],"private_ip_google_access":true,"region":"us-central1","reserved_internal_range":null,"role":null,"send_secondary_ip_range_if_empty":null,"timeouts":null},"sensitive_values":{"log_config":[{}],"params":[],"secondary_ip_range":[]}}],"address":"module.tf_private_pool.module.peered_network[0].module.subnets"}]},{"resources":[{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-icmp\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-icmp","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":[],"protocol":"icmp"}],"deny":[],"description":"Allow ICMP from anywhere","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-icmp","params":[],"priority":65534,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"sensitive_values":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-pool-to-nat\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-pool-to-nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow all from worker pool to NAT gateway","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-pool-to-nat","params":[],"priority":1000,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":["nat-gateway"],"timeouts":null},"sensitive_values":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false],"target_tags":[false]}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-ssh-ingress\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-ssh-ingress","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":["22"],"protocol":"tcp"}],"deny":[],"description":"Allow SSH from anywhere (0.0.0.0/1)","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-ssh-ingress","params":[],"priority":1000,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"sensitive_values":{"allow":[{"ports":[false]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"fw-b-cbpools-100-i-a-all-all-all-service-networking\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"fw-b-cbpools-100-i-a-all-all-all-service-networking","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow ingress from the IPs configured for service networking","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"fw-b-cbpools-100-i-a-all-all-all-service-networking","params":[],"priority":100,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"sensitive_values":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}],"address":"module.tf_private_pool.module.firewall_rules[0]"}]},{"resources":[{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_editor","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/cloudbuild.builds.editor"},"sensitive_values":{"condition":[]}},{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_viewer","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_viewer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_source.google_project_iam_member.org_admins_source_repo_admin[0]","mode":"managed","type":"google_project_iam_member","name":"org_admins_source_repo_admin","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/source.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-bootstrap","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-environments\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-environments","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-environments","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-networks\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-networks","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-networks","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-org\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-org","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-policies\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-policies","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-policies","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-projects\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-projects","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-projects","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"tf-cloudbuilder\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"tf-cloudbuilder","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"tf-cloudbuilder","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_storage_bucket_iam_member.cloudbuild_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"cloudbuild_iam","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_source","child_modules":[{"address":"module.tf_source.module.cloudbuild_project","child_modules":[{"resources":[{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"tags":null,"terraform_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"sensitive_values":{"effective_labels":{},"labels":{},"terraform_labels":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"sensitive_values":{"service_accounts":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","mode":"managed","type":"google_service_account","name":"default_service_account","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"project-service-account","create_ignore_already_exists":true,"description":null,"disabled":false,"timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":0,"values":{"byte_length":2,"keepers":null,"prefix":null},"sensitive_values":{}}],"address":"module.tf_source.module.cloudbuild_project.module.project-factory","child_modules":[{"resources":[{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"artifactregistry.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"artifactregistry.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"artifactregistry.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudscheduler.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudscheduler.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudscheduler.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"dns.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"dns.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"dns.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"sourcerepo.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"sourcerepo.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"sourcerepo.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"workflows.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"workflows.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"workflows.googleapis.com","timeouts":null},"sensitive_values":{}}],"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services"}]}]},{"resources":[{"address":"module.tf_source.module.cloudbuild_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_source.module.cloudbuild_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"bootstrap\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"bootstrap\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket"},{"resources":[{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"env\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"env\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"env\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"env\"].module.log_bucket"},{"resources":[{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"env\"].module.artifacts_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"net\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"net\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"net\"].module.artifacts_bucket"},{"resources":[{"address":"module.tf_workspace[\"net\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"net\"].module.log_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"org\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"org\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"org\"].module.artifacts_bucket"},{"resources":[{"address":"module.tf_workspace[\"org\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"org\"].module.log_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"proj\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"proj\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket"},{"resources":[{"address":"module.tf_workspace[\"proj\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"proj\"].module.log_bucket"}]}]}},"resource_changes":[{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"data.google_project.seed_project","mode":"data","type":"google_project","name":"seed_project","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"bootstrap\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"env\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"net\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"org\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"proj\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_account_sink","mode":"managed","type":"google_billing_account_iam_member","name":"billing_account_sink","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/logging.configWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_folder.bootstrap","mode":"managed","type":"google_folder","name":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"deletion_protection":true,"display_name":"fldr-bootstrap","parent":"folders/49822046027","tags":null,"timeouts":null},"after_unknown":{"create_time":true,"folder_id":true,"id":true,"lifecycle_state":true,"name":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_project_service_identity.workflows_identity","mode":"managed","type":"google_project_service_identity","name":"workflows_identity","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"service":"workflows.googleapis.com","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"bootstrap\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-bootstrap","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Bootstrap SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"env\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-env","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Environment SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"net\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-net","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Network SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"org\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-org","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Organization SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"proj\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-proj","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Projects SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_sourcerepo_repository_iam_member.member[\"bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"env\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"net\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"org\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"proj\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"after_unknown":{"id":true,"result":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"time_sleep.cloud_builder","mode":"managed","type":"time_sleep","name":"cloud_builder","provider_name":"registry.terraform.io/hashicorp/time","change":{"actions":["create"],"before":null,"after":{"create_duration":"30s","destroy_duration":null,"triggers":null},"after_unknown":{"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.bootstrap_csr_repo.null_resource.run_command[0]","module_address":"module.bootstrap_csr_repo","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"create_cmd_entrypoint":"./scripts/push-to-repo.sh","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"ad3634e17109216cf99cbd7242475359"}},"after_unknown":{"id":true,"triggers":{"arguments":true,"create_cmd_body":true}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.bootstrap_csr_repo.null_resource.run_destroy_command[0]","module_address":"module.bootstrap_csr_repo","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin"}},"after_unknown":{"id":true,"triggers":{}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.bootstrap_projects_remove_editor[\"cicd\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","module_address":"module.bootstrap_projects_remove_editor[\"cicd\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"members":null,"role":"roles/editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.bootstrap_projects_remove_editor[\"seed\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","module_address":"module.bootstrap_projects_remove_editor[\"seed\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"members":null,"role":"roles/editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.build_terraform_image.null_resource.module_depends_on[0]","module_address":"module.build_terraform_image","mode":"managed","type":"null_resource","name":"module_depends_on","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"value":"1"}},"after_unknown":{"id":true,"triggers":{}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.build_terraform_image.null_resource.run_command[0]","module_address":"module.build_terraform_image","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"create_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"7f22bf39aaf5ce5980111c3587bef5b5","terraform_version":"1.5.7"}},"after_unknown":{"id":true,"triggers":{"arguments":true,"create_cmd_body":true}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.build_terraform_image.null_resource.run_destroy_command[0]","module_address":"module.build_terraform_image","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","terraform_version":"1.5.7"}},"after_unknown":{"id":true,"triggers":{}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/artifactregistry.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/artifactregistry.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.builds.editor\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.builds.editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.workerPoolOwner\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.workerPoolOwner","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolOwner"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudscheduler.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudscheduler.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudscheduler.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/compute.networkAdmin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/compute.networkAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/dns.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/dns.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.workloadIdentityPoolAdmin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.workloadIdentityPoolAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.workloadIdentityPoolAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/source.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/source.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/source.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/workflows.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/workflows.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/workflows.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.gcp_projects_state_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.gcp_projects_state_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","module_address":"module.gcp_projects_state_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{"default_kms_key_name":true}],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/assuredworkloads.admin\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/assuredworkloads.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/assuredworkloads.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/compute.xpnAdmin\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/compute.xpnAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/cloudasset.owner\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudasset.owner","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/cloudasset.owner"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/essentialcontacts.admin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/essentialcontacts.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/essentialcontacts.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/logging.configWriter\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/logging.configWriter","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/logging.configWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/orgpolicy.policyAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/orgpolicy.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/orgpolicy.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationViewer\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationViewer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationViewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.notificationConfigEditor\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.notificationConfigEditor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.notificationConfigEditor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.sourcesEditor\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.sourcesEditor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.sourcesEditor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/cloudkms.admin\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/cloudkms.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"bootstrap\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"bootstrap\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"env\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"env\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityPolicyAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityPolicyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityPolicyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityResourceAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityResourceAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityResourceAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.securityAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.securityAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.securityAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/dns.admin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/dns.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderViewer\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderViewer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderViewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"org\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"org\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/artifactregistry.admin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/artifactregistry.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.xpnAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.xpnAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/iam.serviceAccountAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/iam.serviceAccountAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.data.google_storage_project_service_account.gcs_account","module_address":"module.seed_bootstrap","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.seed_bootstrap.google_folder_iam_binding.project_creator[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_binding","name":"project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.projectCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"members":true},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[]}}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_service_account_user[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_member","name":"org_admin_service_account_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_serviceusage_consumer[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_member","name":"org_admin_serviceusage_consumer","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_folder_iam_member.tmp_project_creator[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_member","name":"tmp_project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/resourcemanager.projectCreator"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_organization_iam_binding.billing_creator","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_binding","name":"billing_creator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"members":["group:billing_admin_duda_foundation@clsecteam.com"],"org_id":"1055058813388","role":"roles/billing.creator"},"after_unknown":{"condition":[],"etag":true,"id":true,"members":[false]},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[false]}}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/billing.user\"]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/billing.user","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_billing_admin","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_member","name":"org_billing_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:billing_admin_duda_foundation@clsecteam.com","org_id":"1055058813388","role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_storage_bucket.org_terraform_state","module_address":"module.seed_bootstrap","mode":"managed","type":"google_storage_bucket","name":"org_terraform_state","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"requester_pays":null,"retention_policy":[],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{"default_kms_key_name":true}],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"public_access_prevention":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":true,"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.seed_bootstrap.google_storage_bucket_iam_member.orgadmins_state_iam[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_storage_bucket_iam_member","name":"orgadmins_state_iam","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.random_id.suffix","module_address":"module.seed_bootstrap","mode":"managed","type":"random_id","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"byte_length":2,"keepers":null,"prefix":null},"after_unknown":{"b64_std":true,"b64_url":true,"dec":true,"hex":true,"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudkms.admin\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudkms.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"env\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"env\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"net\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"net\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"org\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"org\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"proj\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"proj\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_artifact_registry_repository","name":"tf-image-repo","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"cleanup_policies":[],"cleanup_policy_dry_run":null,"description":"Docker repository for Terraform runner images used by Cloud Build. Managed by Terraform.","docker_config":[],"effective_labels":{"goog-terraform-provisioned":"true"},"format":"DOCKER","kms_key_name":null,"labels":null,"location":"us-central1","maven_config":[],"mode":"STANDARD_REPOSITORY","remote_repository_config":[],"repository_id":"tf-runners","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"virtual_repository_config":[]},"after_unknown":{"cleanup_policies":[],"create_time":true,"docker_config":[],"effective_labels":{},"id":true,"maven_config":[],"name":true,"project":true,"remote_repository_config":[],"terraform_labels":{},"update_time":true,"virtual_repository_config":[],"vulnerability_scanning_config":true},"before_sensitive":false,"after_sensitive":{"cleanup_policies":[],"docker_config":[],"effective_labels":{},"maven_config":[],"remote_repository_config":[],"terraform_labels":{},"virtual_repository_config":[],"vulnerability_scanning_config":[]}}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.push_images","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"push_images","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.writer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.workflow_list","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"workflow_list","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_cloud_scheduler_job.trigger_workflow","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_cloud_scheduler_job","name":"trigger_workflow","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"app_engine_http_target":[],"attempt_deadline":null,"description":"Trigger workflow for TF Runner builds. Managed by Terraform.","http_target":[{"body":null,"headers":null,"http_method":"POST","oauth_token":[{"scope":"https://www.googleapis.com/auth/cloud-platform"}],"oidc_token":[]}],"name":"trigger-terraform-runner-workflow","pubsub_target":[],"region":"us-central1","retry_config":[],"schedule":"0 8 * * *","time_zone":"Etc/UTC","timeouts":null},"after_unknown":{"app_engine_http_target":[],"http_target":[{"oauth_token":[{"service_account_email":true}],"oidc_token":[],"uri":true}],"id":true,"paused":true,"project":true,"pubsub_target":[],"retry_config":[],"state":true},"before_sensitive":false,"after_sensitive":{"app_engine_http_target":[],"http_target":[{"oauth_token":[{}],"oidc_token":[]}],"pubsub_target":[],"retry_config":[]}}},{"address":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_cloudbuild_trigger","name":"build_trigger","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"options":[{"disk_size_gb":null,"dynamic_substitutions":null,"env":null,"log_streaming_option":null,"logging":null,"machine_type":null,"requested_verify_option":null,"secret_env":null,"source_provenance_hash":null,"substitution_option":null,"volumes":[]}],"queue_ttl":null,"secret":[],"source":[],"step":[{"allow_exit_codes":null,"allow_failure":null,"dir":null,"entrypoint":null,"env":null,"id":null,"name":"gcr.io/cloud-builders/docker","script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null},{"allow_exit_codes":null,"allow_failure":null,"args":["version"],"dir":null,"entrypoint":null,"env":null,"id":null,"script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null}],"substitutions":null,"tags":null,"timeout":"1200s"}],"description":"Builds a Terraform runner image. Managed by Terraform.","disabled":null,"filename":null,"filter":null,"git_file_source":[],"github":[],"ignored_files":null,"include_build_logs":null,"included_files":null,"location":"us-central1","name":"tf-cloud-builder-build","pubsub_config":[],"repository_event_config":[],"source_to_build":[{"bitbucket_server_config":null,"github_enterprise_config":null,"ref":"refs/heads/main","repo_type":"CLOUD_SOURCE_REPOSITORIES","repository":null}],"substitutions":{"_TERRAFORM_FULL_VERSION":"1.5.7","_TERRAFORM_MAJOR_VERSION":"1","_TERRAFORM_MINOR_VERSION":"1.5"},"tags":null,"timeouts":null,"trigger_template":[],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"images":true,"logs_bucket":true,"options":[{"volumes":[],"worker_pool":true}],"secret":[],"source":[],"step":[{"args":true,"volumes":[]},{"args":[false],"name":true,"volumes":[]}]}],"create_time":true,"git_file_source":[],"github":[],"id":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[{"uri":true}],"substitutions":{},"trigger_id":true,"trigger_template":[],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"images":[],"options":[{"volumes":[]}],"secret":[],"source":[],"step":[{"args":[],"volumes":[]},{"args":[false],"volumes":[]}]}],"git_file_source":[],"github":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[{}],"substitutions":{},"trigger_template":[],"webhook_config":[]}}},{"address":"module.tf_cloud_builder.google_project_iam_member.invoke_workflow_scheduler","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_project_iam_member","name":"invoke_workflow_scheduler","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/workflows.invoker"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_project_iam_member.logs_writer","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_project_iam_member","name":"logs_writer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_project_iam_member.trigger_builds","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_project_iam_member","name":"trigger_builds","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_service_account.cb_sa[0]","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_service_account","name":"cb_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"tf-cb-builder-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for Terraform builder build trigger. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_cloud_builder.google_service_account.workflow_sa[0]","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_service_account","name":"workflow_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"terraform-runner-workflow-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for TF Builder Workflow. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_cloud_builder.google_service_account_iam_member.use_cb_sa","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_service_account_iam_member","name":"use_cb_sa","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_storage_bucket_iam_member.member","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_storage_bucket_iam_member","name":"member","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_workflows_workflow.builder","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_workflows_workflow","name":"builder","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"call_log_level":null,"crypto_key_name":null,"deletion_protection":true,"description":"Workflow for triggering TF Runner builds. Managed by Terraform.","effective_labels":{"goog-terraform-provisioned":"true"},"execution_history_level":null,"labels":null,"name":"terraform-runner-workflow","region":"us-central1","tags":null,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"user_env_vars":null},"after_unknown":{"create_time":true,"effective_labels":{},"id":true,"name_prefix":true,"project":true,"revision_id":true,"service_account":true,"source_contents":true,"state":true,"terraform_labels":{},"update_time":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"module.tf_private_pool.google_cloudbuild_worker_pool.private_pool","module_address":"module.tf_private_pool","mode":"managed","type":"google_cloudbuild_worker_pool","name":"private_pool","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"annotations":null,"display_name":null,"location":"us-central1","network_config":[{"peered_network_ip_range":null}],"private_service_connect":[],"timeouts":null,"worker_config":[{"disk_size_gb":100,"machine_type":"e2-medium","no_external_ip":true}]},"after_unknown":{"create_time":true,"delete_time":true,"effective_annotations":true,"id":true,"name":true,"network_config":[{"peered_network":true}],"private_service_connect":[],"project":true,"state":true,"uid":true,"update_time":true,"worker_config":[{}]},"before_sensitive":false,"after_sensitive":{"effective_annotations":{},"network_config":[{}],"private_service_connect":[],"worker_config":[{}]}}},{"address":"module.tf_private_pool.google_compute_address.cloud_build_nat","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_address","name":"cloud_build_nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"address_type":"EXTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"ipv6_endpoint_type":null,"labels":null,"name":"cloud-build-nat","network":null,"network_tier":"PREMIUM","region":"us-central1","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"address":true,"creation_timestamp":true,"effective_labels":{},"id":true,"label_fingerprint":true,"prefix_length":true,"project":true,"purpose":true,"self_link":true,"subnetwork":true,"terraform_labels":{},"users":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{},"users":[]}}},{"address":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_global_address","name":"worker_pool_range","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"address":"192.168.0.0","address_type":"INTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"labels":null,"name":"ga-b-cbpools-worker-pool-range","prefix_length":24,"purpose":"VPC_PEERING","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"creation_timestamp":true,"effective_labels":{},"id":true,"label_fingerprint":true,"network":true,"project":true,"self_link":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"module.tf_private_pool.google_compute_instance.vm-proxy","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_instance","name":"vm-proxy","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"advanced_machine_features":[],"allow_stopping_for_update":null,"attached_disk":[],"boot_disk":[{"auto_delete":true,"disk_encryption_key_raw":null,"disk_encryption_key_rsa":null,"disk_encryption_service_account":null,"force_attach":null,"initialize_params":[{"enable_confidential_compute":null,"image":"debian-cloud/debian-12","resource_manager_tags":null,"source_image_encryption_key":[],"source_snapshot_encryption_key":[],"storage_pool":null}],"interface":null,"mode":"READ_WRITE"}],"can_ip_forward":true,"deletion_protection":false,"description":null,"desired_status":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_display":null,"hostname":null,"instance_encryption_key":[],"key_revocation_action_type":null,"labels":null,"machine_type":"e2-medium","metadata":null,"metadata_startup_script":"sysctl -w net.ipv4.ip_forward=1 \u0026\u0026 iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE","name":"cloud-build-nat-vm","network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[],"nic_type":null,"queue_count":null,"subnetwork":"sb-b-cbpools-us-central1"}],"network_performance_config":[],"params":[],"resource_policies":null,"scratch_disk":[],"service_account":[{"scopes":["https://www.googleapis.com/auth/cloud-platform"]}],"shielded_instance_config":[],"tags":["direct-gateway-access","nat-gateway"],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"zone":"us-central1-a"},"after_unknown":{"advanced_machine_features":[],"attached_disk":[],"boot_disk":[{"device_name":true,"disk_encryption_key_sha256":true,"guest_os_features":true,"initialize_params":[{"architecture":true,"labels":true,"provisioned_iops":true,"provisioned_throughput":true,"resource_policies":true,"size":true,"snapshot":true,"source_image_encryption_key":[],"source_snapshot_encryption_key":[],"type":true}],"kms_key_self_link":true,"source":true}],"confidential_instance_config":true,"cpu_platform":true,"creation_timestamp":true,"current_status":true,"effective_labels":{},"guest_accelerator":true,"id":true,"instance_encryption_key":[],"instance_id":true,"label_fingerprint":true,"metadata_fingerprint":true,"min_cpu_platform":true,"network_interface":[{"access_config":[],"alias_ip_range":[],"internal_ipv6_prefix_length":true,"ipv6_access_config":[],"ipv6_access_type":true,"ipv6_address":true,"name":true,"network":true,"network_attachment":true,"network_ip":true,"stack_type":true,"subnetwork_project":true}],"network_performance_config":[],"params":[],"project":true,"reservation_affinity":true,"scheduling":true,"scratch_disk":[],"self_link":true,"service_account":[{"email":true,"scopes":[false]}],"shielded_instance_config":[],"tags":[false,false],"tags_fingerprint":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"advanced_machine_features":[],"attached_disk":[],"boot_disk":[{"disk_encryption_key_raw":true,"disk_encryption_key_rsa":true,"guest_os_features":[],"initialize_params":[{"labels":{},"resource_policies":[],"source_image_encryption_key":[],"source_snapshot_encryption_key":[]}]}],"confidential_instance_config":[],"effective_labels":{},"guest_accelerator":[],"instance_encryption_key":[],"network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[]}],"network_performance_config":[],"params":[],"reservation_affinity":[],"scheduling":[],"scratch_disk":[],"service_account":[{"scopes":[false]}],"shielded_instance_config":[],"tags":[false,false],"terraform_labels":{}}}},{"address":"module.tf_private_pool.google_compute_network_peering_routes_config.peering_routes[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_network_peering_routes_config","name":"peering_routes","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"export_custom_routes":true,"import_custom_routes":true,"timeouts":null},"after_unknown":{"export_subnet_routes_with_public_ip":true,"id":true,"import_subnet_routes_with_public_ip":true,"network":true,"peering":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"direct-to-gateway","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"0.0.0.0/1","name":"direct-to-gateway-range1","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"tags":[false],"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway2","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"direct-to-gateway2","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"128.0.0.0/1","name":"direct-to-gateway-range2","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"tags":[false],"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_route.through-nat","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"through-nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"0.0.0.0/1","name":"through-nat-range1","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_route.through-nat2","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"through-nat2","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"128.0.0.0/1","name":"through-nat-range2","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_router.cb-router","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_router","name":"cb-router","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bgp":[],"description":null,"encrypted_interconnect_router":null,"md5_authentication_keys":[],"name":"cb-cloud-router","region":"us-central1","timeouts":null},"after_unknown":{"bgp":[],"creation_timestamp":true,"id":true,"md5_authentication_keys":[],"network":true,"project":true,"self_link":true},"before_sensitive":false,"after_sensitive":{"bgp":[],"md5_authentication_keys":[]}}},{"address":"module.tf_private_pool.google_compute_router_nat.cb-nat","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_router_nat","name":"cb-nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"icmp_idle_timeout_sec":30,"initial_nat_ips":null,"log_config":[{"enable":true,"filter":"ALL"}],"max_ports_per_vm":null,"name":"cb-cloud-nat","nat64_subnetwork":[],"nat_ip_allocate_option":"AUTO_ONLY","region":"us-central1","router":"cb-cloud-router","rules":[],"source_subnetwork_ip_ranges_to_nat":"ALL_SUBNETWORKS_ALL_IP_RANGES","source_subnetwork_ip_ranges_to_nat64":null,"subnetwork":[],"tcp_established_idle_timeout_sec":1200,"tcp_time_wait_timeout_sec":120,"tcp_transitory_idle_timeout_sec":30,"timeouts":null,"type":"PUBLIC","udp_idle_timeout_sec":30},"after_unknown":{"auto_network_tier":true,"drain_nat_ips":true,"enable_dynamic_port_allocation":true,"enable_endpoint_independent_mapping":true,"endpoint_types":true,"id":true,"log_config":[{}],"min_ports_per_vm":true,"nat64_subnetwork":[],"nat_ips":true,"project":true,"rules":[],"subnetwork":[]},"before_sensitive":false,"after_sensitive":{"drain_nat_ips":[],"endpoint_types":[],"log_config":[{}],"nat64_subnetwork":[],"nat_ips":[],"rules":[],"subnetwork":[]}}},{"address":"module.tf_private_pool.google_dns_policy.default_policy[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_dns_policy","name":"default_policy","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"alternative_name_server_config":[],"description":"Managed by Terraform","enable_inbound_forwarding":true,"enable_logging":true,"name":"dp-b-cbpools-default-policy","networks":[{}],"timeouts":null},"after_unknown":{"alternative_name_server_config":[],"dns64_config":true,"id":true,"networks":[{"network_url":true}],"project":true},"before_sensitive":false,"after_sensitive":{"alternative_name_server_config":[],"dns64_config":[],"networks":[{}]}}},{"address":"module.tf_private_pool.google_service_networking_connection.worker_pool_conn[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_service_networking_connection","name":"worker_pool_conn","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"deletion_policy":null,"reserved_peering_ranges":["ga-b-cbpools-worker-pool-range"],"service":"servicenetworking.googleapis.com","timeouts":null,"update_on_creation_fail":null},"after_unknown":{"id":true,"network":true,"peering":true,"reserved_peering_ranges":[false]},"before_sensitive":false,"after_sensitive":{"reserved_peering_ranges":[false]}}},{"address":"module.tf_private_pool.random_string.suffix","module_address":"module.tf_private_pool","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"after_unknown":{"id":true,"result":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_editor","module_address":"module.tf_source","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/cloudbuild.builds.editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_viewer","module_address":"module.tf_source","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_viewer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_source.google_project_iam_member.org_admins_source_repo_admin[0]","module_address":"module.tf_source","mode":"managed","type":"google_project_iam_member","name":"org_admins_source_repo_admin","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/source.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-bootstrap\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-bootstrap","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-environments\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-environments","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-environments","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-networks\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-networks","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-networks","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-org\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-org","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-policies\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-policies","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-policies","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-projects\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-projects","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-projects","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"tf-cloudbuilder\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"tf-cloudbuilder","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"tf-cloudbuilder","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_storage_bucket_iam_member.cloudbuild_iam","module_address":"module.tf_source","mode":"managed","type":"google_storage_bucket_iam_member","name":"cloudbuild_iam","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"env\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"net\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"org\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage.google_project_organization_policy.project_policy_boolean[0]","module_address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage","mode":"managed","type":"google_project_organization_policy","name":"project_policy_boolean","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"boolean_policy":[{"enforced":false}],"constraint":"constraints/iam.disableCrossProjectServiceAccountUsage","list_policy":[],"restore_policy":[],"timeouts":null},"after_unknown":{"boolean_policy":[{}],"etag":true,"id":true,"list_policy":[],"project":true,"restore_policy":[],"update_time":true,"version":true},"before_sensitive":false,"after_sensitive":{"boolean_policy":[{}],"list_policy":[],"restore_policy":[]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key[0]","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_crypto_key","name":"key","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"effective_labels":{"goog-terraform-provisioned":"true"},"import_only":false,"labels":null,"name":"prj-key","purpose":"ENCRYPT_DECRYPT","rotation_period":"7776000s","skip_initial_version_creation":false,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"version_template":[{"algorithm":"GOOGLE_SYMMETRIC_ENCRYPTION","protection_level":"SOFTWARE"}]},"after_unknown":{"crypto_key_backend":true,"destroy_scheduled_duration":true,"effective_labels":{},"id":true,"key_ring":true,"primary":true,"terraform_labels":{},"version_template":[{}]},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"primary":[],"terraform_labels":{},"version_template":[{}]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.decrypters[0]","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudkms.cryptoKeyDecrypter"},"after_unknown":{"condition":[],"crypto_key_id":true,"etag":true,"id":true,"members":true},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.encrypters[0]","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudkms.cryptoKeyEncrypter"},"after_unknown":{"condition":[],"crypto_key_id":true,"etag":true,"id":true,"members":true},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"location":"us-central1","name":"prj-keyring","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_cloud_builder.module.bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_cloud_builder.module.bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","module_address":"module.tf_cloud_builder.module.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-icmp\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-icmp","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":[],"protocol":"icmp"}],"deny":[],"description":"Allow ICMP from anywhere","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-icmp","params":[],"priority":65534,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"after_unknown":{"allow":[{"ports":[]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-pool-to-nat\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-pool-to-nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow all from worker pool to NAT gateway","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-pool-to-nat","params":[],"priority":1000,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":["nat-gateway"],"timeouts":null},"after_unknown":{"allow":[{"ports":[]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false],"target_tags":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false],"target_tags":[false]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-ssh-ingress\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-ssh-ingress","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":["22"],"protocol":"tcp"}],"deny":[],"description":"Allow SSH from anywhere (0.0.0.0/1)","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-ssh-ingress","params":[],"priority":1000,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"after_unknown":{"allow":[{"ports":[false]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[false]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"fw-b-cbpools-100-i-a-all-all-all-service-networking\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"fw-b-cbpools-100-i-a-all-all-all-service-networking","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow ingress from the IPs configured for service networking","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"fw-b-cbpools-100-i-a-all-all-all-service-networking","params":[],"priority":100,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"after_unknown":{"allow":[{"ports":[]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}},{"address":"module.tf_source.module.cloudbuild_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_source.module.cloudbuild_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","module_address":"module.tf_source.module.cloudbuild_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"bootstrap\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"bootstrap\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"env\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"env\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"env\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"env\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"env\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"net\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"net\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"net\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"net\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"net\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"org\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"org\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"org\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"org\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"org\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"proj\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"proj\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"proj\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"proj\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"proj\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"name":"prj-b-seed","tags":null,"terraform_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"after_unknown":{"effective_labels":{},"folder_id":true,"id":true,"labels":{},"number":true,"org_id":true,"project_id":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"terraform_labels":{}}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"after_unknown":{"id":true,"project":true,"service_accounts":true},"before_sensitive":false,"after_sensitive":{"service_accounts":{}}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_resource_manager_lien.lien[0]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"google_resource_manager_lien","name":"lien","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"origin":"project-factory","reason":"Project Factory lien","restrictions":["resourcemanager.projects.delete"],"timeouts":null},"after_unknown":{"create_time":true,"id":true,"name":true,"parent":true,"restrictions":[false]},"before_sensitive":false,"after_sensitive":{"restrictions":[false]}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.random_id.random_project_id_suffix","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"byte_length":2,"keepers":null,"prefix":null},"after_unknown":{"b64_std":true,"b64_url":true,"dec":true,"hex":true,"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_private_pool.module.peered_network[0].module.subnets.google_compute_subnetwork.subnetwork[\"us-central1/sb-b-cbpools-us-central1\"]","module_address":"module.tf_private_pool.module.peered_network[0].module.subnets","mode":"managed","type":"google_compute_subnetwork","name":"subnetwork","index":"us-central1/sb-b-cbpools-us-central1","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":"Peered subnet for Cloud Build private pool","ip_cidr_range":"10.3.0.0/24","ip_collection":null,"ipv6_access_type":null,"log_config":[{"aggregation_interval":"INTERVAL_5_SEC","filter_expr":"true","flow_sampling":0.5,"metadata":"INCLUDE_ALL_METADATA","metadata_fields":null}],"name":"sb-b-cbpools-us-central1","network":"vpc-b-cbpools","params":[],"private_ip_google_access":true,"region":"us-central1","reserved_internal_range":null,"role":null,"send_secondary_ip_range_if_empty":null,"timeouts":null},"after_unknown":{"creation_timestamp":true,"enable_flow_logs":true,"external_ipv6_prefix":true,"fingerprint":true,"gateway_address":true,"id":true,"internal_ipv6_prefix":true,"ipv6_cidr_range":true,"ipv6_gce_endpoint":true,"log_config":[{}],"params":[],"private_ipv6_google_access":true,"project":true,"purpose":true,"secondary_ip_range":true,"self_link":true,"stack_type":true,"state":true,"subnetwork_id":true},"before_sensitive":false,"after_sensitive":{"log_config":[{}],"params":[],"secondary_ip_range":[]}}},{"address":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","module_address":"module.tf_private_pool.module.peered_network[0].module.vpc","mode":"managed","type":"google_compute_network","name":"network","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"auto_create_subnetworks":false,"delete_default_routes_on_create":true,"description":"","enable_ula_internal_ipv6":false,"mtu":0,"name":"vpc-b-cbpools","network_firewall_policy_enforcement_order":"AFTER_CLASSIC_FIREWALL","network_profile":null,"params":[],"routing_mode":"GLOBAL","timeouts":null},"after_unknown":{"bgp_always_compare_med":true,"bgp_best_path_selection_mode":true,"bgp_inter_region_cost":true,"gateway_ipv4":true,"id":true,"internal_ipv6_range":true,"network_id":true,"numeric_id":true,"params":[],"project":true,"self_link":true},"before_sensitive":false,"after_sensitive":{"params":[]}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"tags":null,"terraform_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"after_unknown":{"effective_labels":{},"folder_id":true,"id":true,"labels":{},"name":true,"number":true,"org_id":true,"project_id":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"terraform_labels":{}}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"after_unknown":{"id":true,"project":true,"service_accounts":true},"before_sensitive":false,"after_sensitive":{"service_accounts":{}}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"google_service_account","name":"default_service_account","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"project-service-account","create_ignore_already_exists":true,"description":null,"disabled":false,"timeouts":null},"after_unknown":{"display_name":true,"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.random_id.random_project_id_suffix","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"byte_length":2,"keepers":null,"prefix":null},"after_unknown":{"b64_std":true,"b64_url":true,"dec":true,"hex":true,"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"accesscontextmanager.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"accesscontextmanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"accesscontextmanager.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"assuredworkloads.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"assuredworkloads.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"assuredworkloads.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudasset.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudasset.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudasset.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudkms.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudkms.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudkms.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"essentialcontacts.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"essentialcontacts.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"essentialcontacts.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iamcredentials.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"iamcredentials.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iamcredentials.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"monitoring.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"monitoring.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"monitoring.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"pubsub.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"pubsub.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"pubsub.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"securitycenter.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"securitycenter.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"securitycenter.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"artifactregistry.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"artifactregistry.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"artifactregistry.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudscheduler.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudscheduler.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudscheduler.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"dns.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"dns.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"dns.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"sourcerepo.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"sourcerepo.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"sourcerepo.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"workflows.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"workflows.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"workflows.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}}],"output_changes":{"bootstrap_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_build_peered_network_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_build_private_worker_pool_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_build_worker_peered_ip_range":{"actions":["create"],"before":null,"after":"192.168.0.0/24","after_unknown":false,"before_sensitive":false,"after_sensitive":false},"cloud_build_worker_range_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_builder_artifact_repo":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloudbuild_project_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloudbuild_project_number":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"common_config":{"actions":["create"],"before":null,"after":{"billing_account":"01AAD1-616217-97513A","default_region":"us-central1","default_region_2":"us-west1","default_region_gcs":"US","default_region_kms":"us","folder_prefix":"fldr","org_id":"1055058813388","parent_folder":"49822046027","parent_id":"folders/49822046027","project_prefix":"prj"},"after_unknown":{"bootstrap_folder_name":true},"before_sensitive":false,"after_sensitive":false},"csr_repos":{"actions":["create"],"before":null,"after":{"gcp-bootstrap":{"name":"gcp-bootstrap"},"gcp-environments":{"name":"gcp-environments"},"gcp-networks":{"name":"gcp-networks"},"gcp-org":{"name":"gcp-org"},"gcp-policies":{"name":"gcp-policies"},"gcp-projects":{"name":"gcp-projects"},"tf-cloudbuilder":{"name":"tf-cloudbuilder"}},"after_unknown":{"gcp-bootstrap":{"id":true,"project":true,"url":true},"gcp-environments":{"id":true,"project":true,"url":true},"gcp-networks":{"id":true,"project":true,"url":true},"gcp-org":{"id":true,"project":true,"url":true},"gcp-policies":{"id":true,"project":true,"url":true},"gcp-projects":{"id":true,"project":true,"url":true},"tf-cloudbuilder":{"id":true,"project":true,"url":true}},"before_sensitive":false,"after_sensitive":false},"environment_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"gcs_bucket_cloudbuild_artifacts":{"actions":["create"],"before":null,"after":{},"after_unknown":{"bootstrap":true,"env":true,"net":true,"org":true,"proj":true},"before_sensitive":false,"after_sensitive":false},"gcs_bucket_cloudbuild_logs":{"actions":["create"],"before":null,"after":{},"after_unknown":{"bootstrap":true,"env":true,"net":true,"org":true,"proj":true},"before_sensitive":false,"after_sensitive":false},"gcs_bucket_tfstate":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"networks_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"optional_groups":{"actions":["create"],"before":null,"after":{"gcp_global_secrets_admin":"","gcp_kms_admin":"","gcp_network_viewer":"","gcp_scc_admin":"","gcp_security_reviewer":""},"after_unknown":false,"before_sensitive":false,"after_sensitive":false},"organization_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"parent_id":{"actions":["create"],"before":null,"after":"folder-49822046027","after_unknown":false,"before_sensitive":false,"after_sensitive":false},"projects_gcs_bucket_tfstate":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"projects_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"required_groups":{"actions":["create"],"before":null,"after":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"},"after_unknown":false,"before_sensitive":false,"after_sensitive":false},"seed_project_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"seed_project_number":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false}},"prior_state":{"format_version":"1.0","terraform_version":"1.5.7","values":{"outputs":{"cloud_build_worker_peered_ip_range":{"sensitive":false,"value":"192.168.0.0/24","type":"string"},"optional_groups":{"sensitive":false,"value":{"gcp_global_secrets_admin":"","gcp_kms_admin":"","gcp_network_viewer":"","gcp_scc_admin":"","gcp_security_reviewer":""},"type":["map","string"]},"parent_id":{"sensitive":false,"value":"folder-49822046027","type":"string"},"required_groups":{"sensitive":false,"value":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"},"type":["map","string"]}},"root_module":{"child_modules":[{"resources":[{"address":"module.bootstrap_csr_repo.data.external.env_override[0]","mode":"data","type":"external","name":"env_override","index":0,"provider_name":"registry.terraform.io/hashicorp/external","schema_version":0,"values":{"id":"-","program":[".terraform/modules/bootstrap_csr_repo/scripts/check_env.sh"],"query":{},"result":{"download":""},"working_dir":null},"sensitive_values":{"program":[false],"query":{},"result":{}}}],"address":"module.bootstrap_csr_repo"},{"resources":[{"address":"module.build_terraform_image.data.external.env_override[0]","mode":"data","type":"external","name":"env_override","index":0,"provider_name":"registry.terraform.io/hashicorp/external","schema_version":0,"values":{"id":"-","program":[".terraform/modules/build_terraform_image/scripts/check_env.sh"],"query":{},"result":{"download":""},"working_dir":null},"sensitive_values":{"program":[false],"query":{},"result":{}}}],"address":"module.build_terraform_image"}]}}},"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google","version_constraint":"\u003e= 3.50.0, != 4.31.0, != 6.26.0, != 6.27.0, \u003c 7.0.0"},"google-beta":{"name":"google-beta","full_name":"registry.terraform.io/hashicorp/google-beta","version_constraint":"\u003e= 3.50.0, != 4.31.0, != 6.26.0, != 6.27.0, \u003c 7.0.0","expressions":{"billing_project":{"references":["var.groups.billing_project","var.groups"]},"user_project_override":{"constant_value":true}}},"module.bootstrap_csr_repo:external":{"name":"external","full_name":"registry.terraform.io/hashicorp/external","version_constraint":"\u003e= 2.2.2","module_address":"module.bootstrap_csr_repo"},"module.bootstrap_csr_repo:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.bootstrap_csr_repo"},"module.build_terraform_image:external":{"name":"external","full_name":"registry.terraform.io/hashicorp/external","version_constraint":"\u003e= 2.2.2","module_address":"module.build_terraform_image"},"module.build_terraform_image:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.build_terraform_image"},"module.seed_bootstrap.module.enable_cross_project_service_account_usage:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage"},"module.seed_bootstrap.module.seed_project.module.project-factory:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory"},"module.seed_bootstrap.module.seed_project.module.project-factory:random":{"name":"random","full_name":"registry.terraform.io/hashicorp/random","version_constraint":"\u003e= 2.2.0","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory"},"module.seed_bootstrap.module.seed_project.module.project-factory:time":{"name":"time","full_name":"registry.terraform.io/hashicorp/time","version_constraint":"\u003e= 0.5.0","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory"},"module.seed_bootstrap.module.seed_project:google-beta":{"name":"google-beta","full_name":"registry.terraform.io/hashicorp/google-beta","version_constraint":"\u003e= 5.41.0, \u003c 7.0.0","module_address":"module.seed_bootstrap.module.seed_project"},"module.tf_source.module.cloudbuild_project.module.project-factory:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory"},"module.tf_source.module.cloudbuild_project.module.project-factory:random":{"name":"random","full_name":"registry.terraform.io/hashicorp/random","version_constraint":"\u003e= 2.2.0","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory"},"module.tf_source.module.cloudbuild_project.module.project-factory:time":{"name":"time","full_name":"registry.terraform.io/hashicorp/time","version_constraint":"\u003e= 0.5.0","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory"},"random":{"name":"random","full_name":"registry.terraform.io/hashicorp/random"},"time":{"name":"time","full_name":"registry.terraform.io/hashicorp/time"}},"root_module":{"outputs":{"bootstrap_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"bootstrap\"].email","google_service_account.terraform-env-sa[\"bootstrap\"]","google_service_account.terraform-env-sa"]},"description":"Bootstrap Step Terraform Account"},"cloud_build_peered_network_id":{"expression":{"references":["module.tf_private_pool.peered_network_id","module.tf_private_pool"]},"description":"The ID of the Cloud Build peered network."},"cloud_build_private_worker_pool_id":{"expression":{"references":["module.tf_private_pool.private_worker_pool_id","module.tf_private_pool"]},"description":"ID of the Cloud Build private worker pool."},"cloud_build_worker_peered_ip_range":{"expression":{"references":["module.tf_private_pool.worker_peered_ip_range","module.tf_private_pool"]},"description":"The IP range of the peered service network."},"cloud_build_worker_range_id":{"expression":{"references":["module.tf_private_pool.worker_range_id","module.tf_private_pool"]},"description":"The Cloud Build private worker IP range ID."},"cloud_builder_artifact_repo":{"expression":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source","var.default_region","module.tf_cloud_builder.artifact_repo","module.tf_cloud_builder"]},"description":"Artifact Registry (AR) Repository created to store TF Cloud Builder images."},"cloudbuild_project_id":{"expression":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"description":"Project where Cloud Build configuration and terraform container image will reside."},"cloudbuild_project_number":{"expression":{"references":["data.google_project.cloudbuild_project.number","data.google_project.cloudbuild_project"]},"description":"The cloudbuild project number."},"common_config":{"expression":{"references":["var.org_id","var.parent_folder","var.billing_account","var.default_region","var.default_region_2","var.default_region_gcs","var.default_region_kms","var.project_prefix","var.folder_prefix","local.parent","google_folder.bootstrap.name","google_folder.bootstrap"]},"description":"Common configuration data to be used in other steps."},"csr_repos":{"expression":{"references":["module.tf_source.csr_repos","module.tf_source"]},"description":"List of Cloud Source Repos created by the module, linked to Cloud Build triggers."},"environment_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"env\"].email","google_service_account.terraform-env-sa[\"env\"]","google_service_account.terraform-env-sa"]},"description":"Environment Step Terraform Account"},"gcs_bucket_cloudbuild_artifacts":{"expression":{"references":["module.tf_workspace","local.bucket_self_link_prefix"]},"description":"Bucket used to store Cloud Build artifacts in cicd project."},"gcs_bucket_cloudbuild_logs":{"expression":{"references":["module.tf_workspace","local.bucket_self_link_prefix"]},"description":"Bucket used to store Cloud Build logs in cicd project."},"gcs_bucket_tfstate":{"expression":{"references":["module.seed_bootstrap.gcs_bucket_tfstate","module.seed_bootstrap"]},"description":"Bucket used for storing terraform state for Foundations Pipelines in Seed Project."},"networks_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"net\"].email","google_service_account.terraform-env-sa[\"net\"]","google_service_account.terraform-env-sa"]},"description":"Networks Step Terraform Account"},"optional_groups":{"expression":{"references":["var.groups.create_optional_groups","var.groups","var.groups.optional_groups","var.groups","module.optional_group"]},"description":"List of Google Groups created that are optional to the Example Foundation steps."},"organization_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"org\"].email","google_service_account.terraform-env-sa[\"org\"]","google_service_account.terraform-env-sa"]},"description":"Organization Step Terraform Account"},"parent_id":{"expression":{"references":["var.parent_folder","local.parent_id","var.org_id"]},"description":"Parent ID service account."},"projects_gcs_bucket_tfstate":{"expression":{"references":["module.gcp_projects_state_bucket.bucket.name","module.gcp_projects_state_bucket.bucket","module.gcp_projects_state_bucket"]},"description":"Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project."},"projects_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"proj\"].email","google_service_account.terraform-env-sa[\"proj\"]","google_service_account.terraform-env-sa"]},"description":"Projects Step Terraform Account"},"required_groups":{"expression":{"references":["var.groups.create_required_groups","var.groups","var.groups.required_groups","var.groups","module.required_group"]},"description":"List of Google Groups created that are required by the Example Foundation steps."},"seed_project_id":{"expression":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]},"description":"Project where service accounts and core APIs will be enabled."},"seed_project_number":{"expression":{"references":["data.google_project.seed_project.number","data.google_project.seed_project"]},"description":"The seed project number."}},"resources":[{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","provider_config_key":"google","expressions":{"location":{"references":["var.default_region"]},"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"project":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"repository":{"references":["local.gar_repository"]},"role":{"constant_value":"roles/artifactregistry.reader"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]}},{"address":"google_billing_account_iam_member.billing_account_sink","mode":"managed","type":"google_billing_account_iam_member","name":"billing_account_sink","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.terraform-env-sa[\"org\"].email","google_service_account.terraform-env-sa[\"org\"]","google_service_account.terraform-env-sa"]},"role":{"constant_value":"roles/logging.configWriter"}},"schema_version":0},{"address":"google_billing_account_iam_member.billing_admin_user","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"role":{"constant_value":"roles/billing.admin"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]},"depends_on":["google_billing_account_iam_member.tf_billing_user"]},{"address":"google_billing_account_iam_member.tf_billing_user","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"role":{"constant_value":"roles/billing.user"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]},"depends_on":["google_service_account.terraform-env-sa"]},{"address":"google_folder.bootstrap","mode":"managed","type":"google_folder","name":"bootstrap","provider_config_key":"google","expressions":{"deletion_protection":{"references":["var.folder_deletion_protection"]},"display_name":{"references":["var.folder_prefix"]},"parent":{"references":["local.parent"]}},"schema_version":0},{"address":"google_project_service_identity.workflows_identity","mode":"managed","type":"google_project_service_identity","name":"workflows_identity","provider_config_key":"google-beta","expressions":{"project":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"service":{"constant_value":"workflows.googleapis.com"}},"schema_version":0,"depends_on":["module.tf_source"]},{"address":"google_service_account.terraform-env-sa","mode":"managed","type":"google_service_account","name":"terraform-env-sa","provider_config_key":"google","expressions":{"account_id":{"references":["each.key"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["each.value"]},"project":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]}},{"address":"google_sourcerepo_repository_iam_member.member","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","provider_config_key":"google","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"project":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"repository":{"references":["module.tf_source.csr_repos[\"gcp-policies\"].name","module.tf_source.csr_repos[\"gcp-policies\"]","module.tf_source.csr_repos","module.tf_source"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_config_key":"random","expressions":{"length":{"constant_value":4},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2},{"address":"time_sleep.cloud_builder","mode":"managed","type":"time_sleep","name":"cloud_builder","provider_config_key":"time","expressions":{"create_duration":{"constant_value":"30s"}},"schema_version":0,"depends_on":["module.tf_cloud_builder","module.bootstrap_csr_repo"]},{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"organization":{"references":["var.org_id"]}},"schema_version":0,"count_expression":{"references":["var.groups.create_required_groups","var.groups","var.groups.create_optional_groups","var.groups"]}},{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_config_key":"google","expressions":{"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]}},"schema_version":0,"depends_on":["module.tf_source"]},{"address":"data.google_project.seed_project","mode":"data","type":"google_project","name":"seed_project","provider_config_key":"google","expressions":{"project_id":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]}},"schema_version":0,"depends_on":["module.seed_bootstrap"]}],"module_calls":{"bootstrap_csr_repo":{"source":"terraform-google-modules/gcloud/google","expressions":{"create_cmd_body":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source","module.tf_source.csr_repos","module.tf_source","local.cloudbuilder_repo","path.module"]},"create_cmd_entrypoint":{"references":["path.module"]},"upgrade":{"constant_value":false}},"module":{"outputs":{"bin_dir":{"expression":{"references":["local.gcloud_bin_path"]},"description":"The full bin path of the modules executables"},"create_cmd_bin":{"expression":{"references":["local.create_cmd_bin"]},"description":"The full bin path \u0026 command used on create"},"destroy_cmd_bin":{"expression":{"references":["local.destroy_cmd_bin"]},"description":"The full bin path \u0026 command used on destroy"},"downloaded":{"expression":{"references":["local.skip_download"]},"depends_on":["local.wait"],"description":"Whether gcloud was downloaded or not"},"wait":{"expression":{"references":["local.wait"]},"description":"An output to use when you want to depend on cmd finishing"}},"resources":[{"address":"null_resource.additional_components","mode":"managed","type":"null_resource","name":"additional_components","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.additional_components_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.additional_components_destroy","mode":"managed","type":"null_resource","name":"additional_components_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.additional_components_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.decompress","mode":"managed","type":"null_resource","name":"decompress","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.decompress_command","local.download_gcloud_command","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.download_gcloud","null_resource.download_jq"]},{"address":"null_resource.decompress_destroy","mode":"managed","type":"null_resource","name":"decompress_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_wrapper","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.decompress_wrapper"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.upgrade_destroy"]},{"address":"null_resource.download_gcloud","mode":"managed","type":"null_resource","name":"download_gcloud","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_gcloud_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_gcloud_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.download_jq","mode":"managed","type":"null_resource","name":"download_jq","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_jq_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.gcloud_auth_google_credentials","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_google_credentials_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_google_credentials_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_google_credentials_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.gcloud_auth_service_account_key_file","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_service_account_key_file_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_service_account_key_file_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_service_account_key_file_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.module_depends_on","mode":"managed","type":"null_resource","name":"module_depends_on","provider_config_key":"module.bootstrap_csr_repo:null","expressions":{"triggers":{"references":["var.module_depends_on"]}},"schema_version":0,"count_expression":{"references":["var.module_depends_on"]}},{"address":"null_resource.prepare_cache","mode":"managed","type":"null_resource","name":"prepare_cache","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.prepare_cache_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.prepare_cache_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.module_depends_on"]},{"address":"null_resource.run_command","mode":"managed","type":"null_resource","name":"run_command","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.create_cmd_entrypoint","self.triggers","self","self.triggers.create_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.run_destroy_command","mode":"managed","type":"null_resource","name":"run_destroy_command","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.destroy_cmd_entrypoint","self.triggers","self","self.triggers.destroy_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.destroy_cmd_entrypoint","var.destroy_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.upgrade","mode":"managed","type":"null_resource","name":"upgrade","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.upgrade_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.decompress"]},{"address":"null_resource.upgrade_destroy","mode":"managed","type":"null_resource","name":"upgrade_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.upgrade_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.additional_components_destroy","null_resource.gcloud_auth_service_account_key_file_destroy","null_resource.gcloud_auth_google_credentials_destroy"]},{"address":"random_id.cache","mode":"managed","type":"random_id","name":"cache","provider_config_key":"random","expressions":{"byte_length":{"constant_value":4}},"schema_version":0,"count_expression":{"references":["local.skip_download"]}},{"address":"data.external.env_override","mode":"data","type":"external","name":"env_override","provider_config_key":"module.bootstrap_csr_repo:external","expressions":{"program":{"references":["path.module"]},"query":{"constant_value":{}}},"schema_version":0,"count_expression":{"references":["var.enabled"]}}],"variables":{"activate_service_account":{"default":true,"description":"Set to false to skip running `gcloud auth activate-service-account`. Optional."},"additional_components":{"default":[],"description":"Additional gcloud CLI components to install. Defaults to none. Valid value are components listed in `gcloud components list`"},"create_cmd_body":{"default":"info","description":"On create, the command body you'd like to run with your entrypoint."},"create_cmd_entrypoint":{"default":"gcloud","description":"On create, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"create_cmd_triggers":{"default":{},"description":"List of any additional triggers to re-run the create command execution when either of values in the maps change. Some keys are reserved and will be overwritten if specified in this option. (eg. `md5`, `arguments`, `download_gcloud_command`, `download_jq_command`, etc. See details in [the source](https://github.com/terraform-google-modules/terraform-google-gcloud/blob/master/main.tf).)"},"destroy_cmd_body":{"default":"info","description":"On destroy, the command body you'd like to run with your entrypoint."},"destroy_cmd_entrypoint":{"default":"gcloud","description":"On destroy, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"enabled":{"default":true,"description":"Flag to optionally disable usage of this module."},"gcloud_download_url":{"default":"","description":"Custom gcloud download url. Optional."},"gcloud_sdk_version":{"default":"481.0.0","description":"The gcloud sdk version to download."},"jq_download_url":{"default":"","description":"Custom jq download url. Optional."},"jq_version":{"default":"1.6","description":"The jq version to download."},"module_depends_on":{"default":[],"description":"List of modules or resources this module depends on."},"platform":{"default":"linux","description":"Platform CLI will run on. Defaults to linux. Valid values: linux, darwin"},"service_account_key_file":{"default":"","description":"Path to service account key file to run `gcloud auth activate-service-account` with. Optional."},"skip_download":{"default":true,"description":"Whether to skip downloading gcloud (assumes gcloud is already available outside the module)"},"upgrade":{"default":true,"description":"Whether to upgrade gcloud at runtime"},"use_tf_google_credentials_env_var":{"default":false,"description":"Use `GOOGLE_CREDENTIALS` environment variable to run `gcloud auth activate-service-account` with. Optional."}}},"version_constraint":"~\u003e 3.1"},"bootstrap_projects_remove_editor":{"source":"./modules/parent-iam-remove-role","expressions":{"parent_id":{"references":["each.value"]},"parent_type":{"constant_value":"project"},"roles":{"constant_value":["roles/editor"]}},"for_each_expression":{"references":["local.bootstrap_projects"]},"module":{"resources":[{"address":"google_folder_iam_binding.iam_remove","mode":"managed","type":"google_folder_iam_binding","name":"iam_remove","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"members":{"constant_value":[]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_binding.iam_remove","mode":"managed","type":"google_organization_iam_binding","name":"iam_remove","provider_config_key":"google","expressions":{"members":{"constant_value":[]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_binding.iam_remove","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","provider_config_key":"google","expressions":{"members":{"constant_value":[]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to remove all members in the parent resource."}}},"depends_on":["module.seed_project_iam_member","module.cicd_project_iam_member"]},"build_terraform_image":{"source":"terraform-google-modules/gcloud/google","expressions":{"create_cmd_body":{"references":["local.cloud_builder_trigger_id","var.default_region","module.tf_source.cloudbuild_project_id","module.tf_source"]},"create_cmd_triggers":{"references":["local.terraform_version"]},"module_depends_on":{"references":["time_sleep.cloud_builder"]},"upgrade":{"constant_value":false}},"module":{"outputs":{"bin_dir":{"expression":{"references":["local.gcloud_bin_path"]},"description":"The full bin path of the modules executables"},"create_cmd_bin":{"expression":{"references":["local.create_cmd_bin"]},"description":"The full bin path \u0026 command used on create"},"destroy_cmd_bin":{"expression":{"references":["local.destroy_cmd_bin"]},"description":"The full bin path \u0026 command used on destroy"},"downloaded":{"expression":{"references":["local.skip_download"]},"depends_on":["local.wait"],"description":"Whether gcloud was downloaded or not"},"wait":{"expression":{"references":["local.wait"]},"description":"An output to use when you want to depend on cmd finishing"}},"resources":[{"address":"null_resource.additional_components","mode":"managed","type":"null_resource","name":"additional_components","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.additional_components_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.additional_components_destroy","mode":"managed","type":"null_resource","name":"additional_components_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.additional_components_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.decompress","mode":"managed","type":"null_resource","name":"decompress","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.decompress_command","local.download_gcloud_command","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.download_gcloud","null_resource.download_jq"]},{"address":"null_resource.decompress_destroy","mode":"managed","type":"null_resource","name":"decompress_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_wrapper","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.decompress_wrapper"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.upgrade_destroy"]},{"address":"null_resource.download_gcloud","mode":"managed","type":"null_resource","name":"download_gcloud","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_gcloud_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_gcloud_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.download_jq","mode":"managed","type":"null_resource","name":"download_jq","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_jq_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.gcloud_auth_google_credentials","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_google_credentials_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_google_credentials_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_google_credentials_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.gcloud_auth_service_account_key_file","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_service_account_key_file_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_service_account_key_file_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_service_account_key_file_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.module_depends_on","mode":"managed","type":"null_resource","name":"module_depends_on","provider_config_key":"module.build_terraform_image:null","expressions":{"triggers":{"references":["var.module_depends_on"]}},"schema_version":0,"count_expression":{"references":["var.module_depends_on"]}},{"address":"null_resource.prepare_cache","mode":"managed","type":"null_resource","name":"prepare_cache","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.prepare_cache_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.prepare_cache_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.module_depends_on"]},{"address":"null_resource.run_command","mode":"managed","type":"null_resource","name":"run_command","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.create_cmd_entrypoint","self.triggers","self","self.triggers.create_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.run_destroy_command","mode":"managed","type":"null_resource","name":"run_destroy_command","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.destroy_cmd_entrypoint","self.triggers","self","self.triggers.destroy_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.destroy_cmd_entrypoint","var.destroy_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.upgrade","mode":"managed","type":"null_resource","name":"upgrade","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.upgrade_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.decompress"]},{"address":"null_resource.upgrade_destroy","mode":"managed","type":"null_resource","name":"upgrade_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.upgrade_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.additional_components_destroy","null_resource.gcloud_auth_service_account_key_file_destroy","null_resource.gcloud_auth_google_credentials_destroy"]},{"address":"random_id.cache","mode":"managed","type":"random_id","name":"cache","provider_config_key":"random","expressions":{"byte_length":{"constant_value":4}},"schema_version":0,"count_expression":{"references":["local.skip_download"]}},{"address":"data.external.env_override","mode":"data","type":"external","name":"env_override","provider_config_key":"module.build_terraform_image:external","expressions":{"program":{"references":["path.module"]},"query":{"constant_value":{}}},"schema_version":0,"count_expression":{"references":["var.enabled"]}}],"variables":{"activate_service_account":{"default":true,"description":"Set to false to skip running `gcloud auth activate-service-account`. Optional."},"additional_components":{"default":[],"description":"Additional gcloud CLI components to install. Defaults to none. Valid value are components listed in `gcloud components list`"},"create_cmd_body":{"default":"info","description":"On create, the command body you'd like to run with your entrypoint."},"create_cmd_entrypoint":{"default":"gcloud","description":"On create, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"create_cmd_triggers":{"default":{},"description":"List of any additional triggers to re-run the create command execution when either of values in the maps change. Some keys are reserved and will be overwritten if specified in this option. (eg. `md5`, `arguments`, `download_gcloud_command`, `download_jq_command`, etc. See details in [the source](https://github.com/terraform-google-modules/terraform-google-gcloud/blob/master/main.tf).)"},"destroy_cmd_body":{"default":"info","description":"On destroy, the command body you'd like to run with your entrypoint."},"destroy_cmd_entrypoint":{"default":"gcloud","description":"On destroy, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"enabled":{"default":true,"description":"Flag to optionally disable usage of this module."},"gcloud_download_url":{"default":"","description":"Custom gcloud download url. Optional."},"gcloud_sdk_version":{"default":"481.0.0","description":"The gcloud sdk version to download."},"jq_download_url":{"default":"","description":"Custom jq download url. Optional."},"jq_version":{"default":"1.6","description":"The jq version to download."},"module_depends_on":{"default":[],"description":"List of modules or resources this module depends on."},"platform":{"default":"linux","description":"Platform CLI will run on. Defaults to linux. Valid values: linux, darwin"},"service_account_key_file":{"default":"","description":"Path to service account key file to run `gcloud auth activate-service-account` with. Optional."},"skip_download":{"default":true,"description":"Whether to skip downloading gcloud (assumes gcloud is already available outside the module)"},"upgrade":{"default":true,"description":"Whether to upgrade gcloud at runtime"},"use_tf_google_credentials_env_var":{"default":false,"description":"Use `GOOGLE_CREDENTIALS` environment variable to run `gcloud auth activate-service-account` with. Optional."}}},"version_constraint":"~\u003e 3.1"},"cicd_project_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["local.cicd_project_id"]},"parent_type":{"constant_value":"project"},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_cicd_project"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"gcp_projects_state_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"encryption":{"references":["local.state_bucket_kms_key"]},"force_destroy":{"references":["var.bucket_force_destroy"]},"location":{"references":["var.default_region"]},"name":{"references":["var.bucket_prefix","module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]},"project_id":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0","depends_on":["module.seed_bootstrap.gcs_bucket_tfstate"]},"optional_group":{"source":"terraform-google-modules/group/google","expressions":{"customer_id":{"references":["data.google_organization.org[0].directory_customer_id","data.google_organization.org[0]","data.google_organization.org"]},"description":{"references":["each.key"]},"display_name":{"references":["each.key"]},"id":{"references":["each.value"]},"initial_group_config":{"references":["var.initial_group_config"]}},"for_each_expression":{"references":["local.optional_groups_to_create"]},"module":{"outputs":{"id":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"ID of the group. For Google-managed entities, the ID is the email address the group"},"name":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"Name of the group with the domain removed. For Google-managed entities, the ID is the email address the group"},"resource_name":{"expression":{"references":["google_cloud_identity_group.group.name","google_cloud_identity_group.group"]},"description":"Resource name of the group in the format: groups/{group_id}, where group_id is the unique ID assigned to the group."}},"resources":[{"address":"google_cloud_identity_group.group","mode":"managed","type":"google_cloud_identity_group","name":"group","provider_config_key":"google-beta","expressions":{"description":{"references":["var.description"]},"display_name":{"references":["var.display_name"]},"group_key":[{"id":{"references":["var.id"]}}],"initial_group_config":{"references":["var.initial_group_config"]},"labels":{"references":["var.types","local.label_keys"]},"parent":{"references":["local.customer_id"]}},"schema_version":0},{"address":"google_cloud_identity_group_membership.managers","mode":"managed","type":"google_cloud_identity_group_membership","name":"managers","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}},{"name":{"constant_value":"MANAGER"}}]},"schema_version":0,"for_each_expression":{"references":["var.managers"]}},{"address":"google_cloud_identity_group_membership.members","mode":"managed","type":"google_cloud_identity_group_membership","name":"members","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.members"]}},{"address":"google_cloud_identity_group_membership.owners","mode":"managed","type":"google_cloud_identity_group_membership","name":"owners","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"OWNER"}},{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.owners"]}},{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"domain":{"references":["var.domain"]}},"schema_version":0,"count_expression":{"references":["var.domain"]}}],"variables":{"customer_id":{"default":"","description":"Customer ID of the organization to create the group in. One of domain or customer_id must be specified"},"description":{"default":"","description":"Description of the group"},"display_name":{"default":"","description":"Display name of the group"},"domain":{"default":"","description":"Domain of the organization to create the group in. One of domain or customer_id must be specified"},"id":{"description":"ID of the group. For Google-managed entities, the ID must be the email address the group"},"initial_group_config":{"default":"EMPTY","description":"The initial configuration options for creating a Group. See the API reference for possible values. Possible values are INITIAL_GROUP_CONFIG_UNSPECIFIED, WITH_INITIAL_OWNER, and EMPTY."},"managers":{"default":[],"description":"Managers of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"members":{"default":[],"description":"Members of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"owners":{"default":[],"description":"Owners of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"types":{"default":["default"],"description":"The type of the group to be created. More info: https://cloud.google.com/identity/docs/groups#group_properties"}}},"version_constraint":"~\u003e 0.7"},"org_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["var.org_id"]},"parent_type":{"constant_value":"organization"},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_org_level_roles"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"parent_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["local.parent_id"]},"parent_type":{"references":["local.parent_type"]},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_parent_level_roles"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"required_group":{"source":"terraform-google-modules/group/google","expressions":{"customer_id":{"references":["data.google_organization.org[0].directory_customer_id","data.google_organization.org[0]","data.google_organization.org"]},"description":{"references":["each.key"]},"display_name":{"references":["each.key"]},"id":{"references":["each.value"]},"initial_group_config":{"references":["var.initial_group_config"]}},"for_each_expression":{"references":["local.required_groups_to_create"]},"module":{"outputs":{"id":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"ID of the group. For Google-managed entities, the ID is the email address the group"},"name":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"Name of the group with the domain removed. For Google-managed entities, the ID is the email address the group"},"resource_name":{"expression":{"references":["google_cloud_identity_group.group.name","google_cloud_identity_group.group"]},"description":"Resource name of the group in the format: groups/{group_id}, where group_id is the unique ID assigned to the group."}},"resources":[{"address":"google_cloud_identity_group.group","mode":"managed","type":"google_cloud_identity_group","name":"group","provider_config_key":"google-beta","expressions":{"description":{"references":["var.description"]},"display_name":{"references":["var.display_name"]},"group_key":[{"id":{"references":["var.id"]}}],"initial_group_config":{"references":["var.initial_group_config"]},"labels":{"references":["var.types","local.label_keys"]},"parent":{"references":["local.customer_id"]}},"schema_version":0},{"address":"google_cloud_identity_group_membership.managers","mode":"managed","type":"google_cloud_identity_group_membership","name":"managers","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}},{"name":{"constant_value":"MANAGER"}}]},"schema_version":0,"for_each_expression":{"references":["var.managers"]}},{"address":"google_cloud_identity_group_membership.members","mode":"managed","type":"google_cloud_identity_group_membership","name":"members","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.members"]}},{"address":"google_cloud_identity_group_membership.owners","mode":"managed","type":"google_cloud_identity_group_membership","name":"owners","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"OWNER"}},{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.owners"]}},{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"domain":{"references":["var.domain"]}},"schema_version":0,"count_expression":{"references":["var.domain"]}}],"variables":{"customer_id":{"default":"","description":"Customer ID of the organization to create the group in. One of domain or customer_id must be specified"},"description":{"default":"","description":"Description of the group"},"display_name":{"default":"","description":"Display name of the group"},"domain":{"default":"","description":"Domain of the organization to create the group in. One of domain or customer_id must be specified"},"id":{"description":"ID of the group. For Google-managed entities, the ID must be the email address the group"},"initial_group_config":{"default":"EMPTY","description":"The initial configuration options for creating a Group. See the API reference for possible values. Possible values are INITIAL_GROUP_CONFIG_UNSPECIFIED, WITH_INITIAL_OWNER, and EMPTY."},"managers":{"default":[],"description":"Managers of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"members":{"default":[],"description":"Members of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"owners":{"default":[],"description":"Owners of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"types":{"default":["default"],"description":"The type of the group to be created. More info: https://cloud.google.com/identity/docs/groups#group_properties"}}},"version_constraint":"~\u003e 0.7"},"seed_bootstrap":{"source":"terraform-google-modules/bootstrap/google","expressions":{"activate_apis":{"constant_value":["serviceusage.googleapis.com","servicenetworking.googleapis.com","cloudkms.googleapis.com","compute.googleapis.com","logging.googleapis.com","bigquery.googleapis.com","cloudresourcemanager.googleapis.com","cloudbilling.googleapis.com","cloudbuild.googleapis.com","iam.googleapis.com","admin.googleapis.com","appengine.googleapis.com","storage-api.googleapis.com","monitoring.googleapis.com","pubsub.googleapis.com","securitycenter.googleapis.com","accesscontextmanager.googleapis.com","billingbudgets.googleapis.com","essentialcontacts.googleapis.com","assuredworkloads.googleapis.com","cloudasset.googleapis.com"]},"billing_account":{"references":["var.billing_account"]},"create_terraform_sa":{"constant_value":false},"default_region":{"references":["var.default_region"]},"encrypt_gcs_bucket_tfstate":{"constant_value":true},"folder_id":{"references":["google_folder.bootstrap.id","google_folder.bootstrap"]},"force_destroy":{"references":["var.bucket_force_destroy"]},"group_billing_admins":{"references":["var.groups.required_groups.group_billing_admins","var.groups.required_groups","var.groups"]},"group_org_admins":{"references":["var.groups.required_groups.group_org_admins","var.groups.required_groups","var.groups"]},"key_rotation_period":{"constant_value":"7776000s"},"kms_prevent_destroy":{"references":["var.bucket_tfstate_kms_force_destroy"]},"org_admins_org_iam_permissions":{"references":["local.org_admins_org_iam_permissions"]},"org_id":{"references":["var.org_id"]},"org_project_creators":{"references":["local.step_terraform_sa"]},"parent_folder":{"references":["var.parent_folder","local.parent"]},"project_deletion_policy":{"references":["var.project_deletion_policy"]},"project_id":{"references":["var.project_prefix"]},"project_labels":{"constant_value":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"}},"project_prefix":{"references":["var.project_prefix"]},"sa_enable_impersonation":{"constant_value":true},"sa_org_iam_permissions":{"constant_value":[]},"state_bucket_name":{"references":["var.bucket_prefix","var.project_prefix"]}},"module":{"outputs":{"gcs_bucket_tfstate":{"expression":{"references":["google_storage_bucket.org_terraform_state.name","google_storage_bucket.org_terraform_state"]},"description":"Bucket used for storing terraform state for foundations pipelines in seed project."},"seed_project_id":{"expression":{"references":["module.seed_project.project_id","module.seed_project"]},"description":"Project where service accounts and core APIs will be enabled."},"terraform_sa_email":{"expression":{"references":["var.create_terraform_sa","google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"depends_on":["google_organization_iam_member.tf_sa_org_perms","google_billing_account_iam_member.tf_billing_user","google_storage_bucket_iam_member.org_terraform_state_iam","google_service_account_iam_member.org_admin_sa_user","google_service_account_iam_member.org_admin_sa_impersonate_permissions","google_organization_iam_member.org_admin_serviceusage_consumer","google_folder_iam_member.org_admin_service_account_user","google_folder_iam_member.org_admin_serviceusage_consumer","google_storage_bucket_iam_member.orgadmins_state_iam"],"description":"Email for privileged service account for Terraform."},"terraform_sa_name":{"expression":{"references":["var.create_terraform_sa","google_service_account.org_terraform[0].name","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"description":"Fully qualified name for privileged service account for Terraform."}},"resources":[{"address":"google_billing_account_iam_member.tf_billing_user","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"role":{"constant_value":"roles/billing.user"}},"schema_version":0,"count_expression":{"references":["var.grant_billing_user","var.create_terraform_sa"]}},{"address":"google_folder_iam_binding.project_creator","mode":"managed","type":"google_folder_iam_binding","name":"project_creator","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"members":{"references":["local.org_project_creators"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_folder_iam_member.org_admin_service_account_user","mode":"managed","type":"google_folder_iam_member","name":"org_admin_service_account_user","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/iam.serviceAccountUser"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","local.is_organization"]}},{"address":"google_folder_iam_member.org_admin_serviceusage_consumer","mode":"managed","type":"google_folder_iam_member","name":"org_admin_serviceusage_consumer","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/serviceusage.serviceUsageConsumer"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","local.is_organization"]}},{"address":"google_folder_iam_member.tmp_project_creator","mode":"managed","type":"google_folder_iam_member","name":"tmp_project_creator","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_organization_iam_binding.billing_creator","mode":"managed","type":"google_organization_iam_binding","name":"billing_creator","provider_config_key":"google","expressions":{"members":{"references":["var.group_billing_admins"]},"org_id":{"references":["var.org_id"]},"role":{"constant_value":"roles/billing.creator"}},"schema_version":0},{"address":"google_organization_iam_binding.project_creator","mode":"managed","type":"google_organization_iam_binding","name":"project_creator","provider_config_key":"google","expressions":{"members":{"references":["local.org_project_creators"]},"org_id":{"references":["local.parent_id"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_organization_iam_member.org_admin_serviceusage_consumer","mode":"managed","type":"google_organization_iam_member","name":"org_admin_serviceusage_consumer","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"org_id":{"references":["local.parent_id"]},"role":{"constant_value":"roles/serviceusage.serviceUsageConsumer"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","local.is_organization"]}},{"address":"google_organization_iam_member.org_admins_group","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"org_id":{"references":["var.org_id"]},"role":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.org_admins_org_iam_permissions"]}},{"address":"google_organization_iam_member.org_billing_admin","mode":"managed","type":"google_organization_iam_member","name":"org_billing_admin","provider_config_key":"google","expressions":{"member":{"references":["var.group_billing_admins"]},"org_id":{"references":["var.org_id"]},"role":{"constant_value":"roles/billing.admin"}},"schema_version":0},{"address":"google_organization_iam_member.tf_sa_org_perms","mode":"managed","type":"google_organization_iam_member","name":"tf_sa_org_perms","provider_config_key":"google","expressions":{"member":{"references":["google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"org_id":{"references":["var.org_id"]},"role":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.create_terraform_sa","var.sa_org_iam_permissions"]}},{"address":"google_organization_iam_member.tmp_project_creator","mode":"managed","type":"google_organization_iam_member","name":"tmp_project_creator","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"org_id":{"references":["local.parent_id"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_service_account.org_terraform","mode":"managed","type":"google_service_account","name":"org_terraform","provider_config_key":"google","expressions":{"account_id":{"references":["var.tf_service_account_id"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["var.tf_service_account_name"]},"project":{"references":["module.seed_project.project_id","module.seed_project"]}},"schema_version":0,"count_expression":{"references":["var.create_terraform_sa"]}},{"address":"google_service_account_iam_member.org_admin_sa_impersonate_permissions","mode":"managed","type":"google_service_account_iam_member","name":"org_admin_sa_impersonate_permissions","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/iam.serviceAccountTokenCreator"},"service_account_id":{"references":["google_service_account.org_terraform[0].name","google_service_account.org_terraform[0]","google_service_account.org_terraform"]}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","var.create_terraform_sa"]}},{"address":"google_service_account_iam_member.org_admin_sa_user","mode":"managed","type":"google_service_account_iam_member","name":"org_admin_sa_user","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["google_service_account.org_terraform[0].name","google_service_account.org_terraform[0]","google_service_account.org_terraform"]}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","var.create_terraform_sa"]}},{"address":"google_storage_bucket.org_terraform_state","mode":"managed","type":"google_storage_bucket","name":"org_terraform_state","provider_config_key":"google","expressions":{"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.storage_bucket_labels"]},"location":{"references":["var.default_region"]},"name":{"references":["local.state_bucket_name"]},"project":{"references":["module.seed_project.project_id","module.seed_project"]},"uniform_bucket_level_access":{"constant_value":true},"versioning":[{"enabled":{"constant_value":true}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.org_terraform_state_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"org_terraform_state_iam","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.org_terraform_state.name","google_storage_bucket.org_terraform_state"]},"member":{"references":["google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["var.create_terraform_sa"]}},{"address":"google_storage_bucket_iam_member.orgadmins_state_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"orgadmins_state_iam","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.org_terraform_state.name","google_storage_bucket.org_terraform_state"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation"]}},{"address":"random_id.suffix","mode":"managed","type":"random_id","name":"suffix","provider_config_key":"random","expressions":{"byte_length":{"constant_value":2}},"schema_version":0},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["module.seed_project.project_id","module.seed_project"]}},"schema_version":0,"depends_on":["module.seed_project.project_id"]}],"module_calls":{"enable_cross_project_service_account_usage":{"source":"terraform-google-modules/org-policy/google","expressions":{"constraint":{"constant_value":"constraints/iam.disableCrossProjectServiceAccountUsage"},"enforce":{"constant_value":"false"},"policy_for":{"constant_value":"project"},"policy_type":{"constant_value":"boolean"},"project_id":{"references":["module.seed_project.project_id","module.seed_project"]}},"module":{"resources":[{"address":"google_folder_organization_policy.folder_policy_boolean","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_boolean","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]}},"schema_version":0,"count_expression":{"references":["local.folder","local.boolean_policy"]}},{"address":"google_folder_organization_policy.folder_policy_list_allow_all","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_allow_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"allow":[{"all":{"constant_value":true}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","local.enforce"]}},{"address":"google_folder_organization_policy.folder_policy_list_allow_values","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_allow_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"allow":[{"values":{"references":["var.allow"]}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","var.allow_list_length"]}},{"address":"google_folder_organization_policy.folder_policy_list_deny_all","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_deny_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"deny":[{"all":{"constant_value":true}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","local.enforce"]}},{"address":"google_folder_organization_policy.folder_policy_list_deny_values","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_deny_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"deny":[{"values":{"references":["var.deny"]}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","var.deny_list_length"]}},{"address":"google_folder_organization_policy.folder_policy_list_exclude_folders","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_exclude_folders","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["each.value"]},"restore_policy":[{"default":{"constant_value":true}}]},"schema_version":0,"for_each_expression":{"references":["local.list_policy","local.project","var.exclude_folders"]}},{"address":"google_folder_organization_policy.policy_boolean_exclude_folders","mode":"managed","type":"google_folder_organization_policy","name":"policy_boolean_exclude_folders","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"folder":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.boolean_policy","local.project","var.exclude_folders"]}},{"address":"google_organization_policy.org_policy_boolean","mode":"managed","type":"google_organization_policy","name":"org_policy_boolean","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.boolean_policy"]}},{"address":"google_organization_policy.org_policy_list_allow_all","mode":"managed","type":"google_organization_policy","name":"org_policy_list_allow_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"all":{"constant_value":true}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","local.enforce"]}},{"address":"google_organization_policy.org_policy_list_allow_values","mode":"managed","type":"google_organization_policy","name":"org_policy_list_allow_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"values":{"references":["var.allow"]}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","var.allow_list_length"]}},{"address":"google_organization_policy.org_policy_list_deny_all","mode":"managed","type":"google_organization_policy","name":"org_policy_list_deny_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"all":{"constant_value":true}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","local.enforce"]}},{"address":"google_organization_policy.org_policy_list_deny_values","mode":"managed","type":"google_organization_policy","name":"org_policy_list_deny_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"values":{"references":["var.deny"]}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","var.deny_list_length"]}},{"address":"google_project_organization_policy.policy_boolean_exclude_projects","mode":"managed","type":"google_project_organization_policy","name":"policy_boolean_exclude_projects","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"project":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.boolean_policy","local.project","var.exclude_projects"]}},{"address":"google_project_organization_policy.project_policy_boolean","mode":"managed","type":"google_project_organization_policy","name":"project_policy_boolean","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.boolean_policy"]}},{"address":"google_project_organization_policy.project_policy_list_allow_all","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_allow_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"all":{"constant_value":true}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","local.enforce"]}},{"address":"google_project_organization_policy.project_policy_list_allow_values","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_allow_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"values":{"references":["var.allow"]}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","var.allow_list_length"]}},{"address":"google_project_organization_policy.project_policy_list_deny_all","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_deny_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"all":{"constant_value":true}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","local.enforce"]}},{"address":"google_project_organization_policy.project_policy_list_deny_values","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_deny_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"values":{"references":["var.deny"]}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","var.deny_list_length"]}},{"address":"google_project_organization_policy.project_policy_list_exclude_projects","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_exclude_projects","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"project":{"references":["each.value"]},"restore_policy":[{"default":{"constant_value":true}}]},"schema_version":0,"for_each_expression":{"references":["local.list_policy","local.project","var.exclude_projects"]}},{"address":"null_resource.config_check","mode":"managed","type":"null_resource","name":"config_check","provider_config_key":"module.seed_bootstrap.module.enable_cross_project_service_account_usage:null","provisioners":[{"type":"local-exec","expressions":{"command":{"constant_value":"echo 'For list constraints only one of enforce, allow, and deny may be included.'; false"}}}],"schema_version":0,"count_expression":{"references":["local.invalid_config"]}}],"variables":{"allow":{"default":[""],"description":"(Only for list constraints) List of values which should be allowed"},"allow_list_length":{"default":0,"description":"The number of elements in the allow list"},"constraint":{"description":"The constraint to be applied"},"deny":{"default":[""],"description":"(Only for list constraints) List of values which should be denied"},"deny_list_length":{"default":0,"description":"The number of elements in the deny list"},"enforce":{"default":null,"description":"If boolean constraint, whether the policy is enforced at the root; if list constraint, whether to deny all (true) or allow all"},"exclude_folders":{"default":[],"description":"Set of folders to exclude from the policy"},"exclude_projects":{"default":[],"description":"Set of projects to exclude from the policy"},"folder_id":{"default":null,"description":"The folder id for putting the policy"},"organization_id":{"default":null,"description":"The organization id for putting the policy"},"policy_for":{"description":"Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`."},"policy_type":{"default":"list","description":"The constraint type to work with (either 'boolean' or 'list')"},"project_id":{"default":null,"description":"The project id for putting the policy"}}},"version_constraint":"~\u003e 6.0"},"kms":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_protection_level":{"references":["var.key_protection_level"]},"key_rotation_period":{"references":["var.key_rotation_period"]},"keyring":{"references":["var.project_prefix"]},"keys":{"references":["var.project_prefix"]},"location":{"references":["var.default_region"]},"prevent_destroy":{"references":["var.kms_prevent_destroy"]},"project_id":{"references":["module.seed_project.project_id","module.seed_project"]},"set_decrypters_for":{"references":["var.project_prefix"]},"set_encrypters_for":{"references":["var.project_prefix"]}},"count_expression":{"references":["var.encrypt_gcs_bucket_tfstate"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.2"},"seed_project":{"source":"terraform-google-modules/project-factory/google","expressions":{"activate_apis":{"references":["local.activate_apis"]},"auto_create_network":{"references":["var.project_auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"create_project_sa":{"constant_value":false},"deletion_policy":{"references":["var.project_deletion_policy"]},"disable_services_on_destroy":{"constant_value":false},"folder_id":{"references":["var.folder_id"]},"labels":{"references":["var.project_labels"]},"lien":{"constant_value":true},"name":{"references":["local.seed_project_id"]},"org_id":{"references":["local.seed_org_depends_on"]},"random_project_id":{"references":["var.random_suffix"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["module.project-factory.api_s_account","module.project-factory"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["module.project-factory.api_s_account_fmt","module.project-factory"]},"description":"API service account email formatted for terraform use"},"budget_name":{"expression":{"references":["module.budget.name","module.budget"]},"description":"The name of the budget if created"},"domain":{"expression":{"references":["module.gsuite_group.domain","module.gsuite_group"]},"description":"The organization's domain"},"enabled_api_identities":{"expression":{"references":["module.project-factory.enabled_api_identities","module.project-factory"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project-factory.enabled_apis","module.project-factory"]},"description":"Enabled APIs in the project"},"group_email":{"expression":{"references":["module.gsuite_group.email","module.gsuite_group"]},"description":"The email of the G Suite group with group_name"},"project_bucket_self_link":{"expression":{"references":["module.project-factory.project_bucket_self_link","module.project-factory"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["module.project-factory.project_bucket_url","module.project-factory"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project-factory.project_id","module.project-factory"]},"description":"ID of the project"},"project_name":{"expression":{"references":["module.project-factory.project_name","module.project-factory"]},"description":"Name of the project"},"project_number":{"expression":{"references":["module.project-factory.project_number","module.project-factory"]},"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["module.project-factory.service_account_display_name","module.project-factory"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["module.project-factory.service_account_email","module.project-factory"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["module.project-factory.service_account_id","module.project-factory"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["module.project-factory.service_account_name","module.project-factory"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["module.project-factory.service_account_unique_id","module.project-factory"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["module.project-factory.tag_bindings","module.project-factory"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["module.project-factory.usage_report_export_bucket","module.project-factory"]},"description":"GCE usage reports bucket"}},"module_calls":{"budget":{"source":"./modules/budget","expressions":{"alert_pubsub_topic":{"references":["var.budget_alert_pubsub_topic"]},"alert_spend_basis":{"references":["var.budget_alert_spend_basis"]},"alert_spent_percents":{"references":["var.budget_alert_spent_percents"]},"amount":{"references":["var.budget_amount"]},"billing_account":{"references":["var.billing_account"]},"calendar_period":{"references":["var.budget_calendar_period"]},"create_budget":{"references":["var.budget_amount"]},"custom_period_end_date":{"references":["var.budget_custom_period_end_date"]},"custom_period_start_date":{"references":["var.budget_custom_period_start_date"]},"display_name":{"references":["var.budget_display_name","var.budget_display_name"]},"labels":{"references":["var.budget_labels"]},"monitoring_notification_channels":{"references":["var.budget_monitoring_notification_channels"]},"projects":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"name":{"expression":{"references":["google_billing_budget.budget","google_billing_budget.budget[0].name","google_billing_budget.budget[0]","google_billing_budget.budget"]},"description":"Resource name of the budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}.`"}},"resources":[{"address":"google_billing_budget.budget","mode":"managed","type":"google_billing_budget","name":"budget","provider_config_key":"google","expressions":{"amount":[{"specified_amount":[{"units":{"references":["var.amount"]}}]}],"billing_account":{"references":["var.billing_account"]},"budget_filter":[{"calendar_period":{"references":["local.custom_period","var.calendar_period"]},"credit_types_treatment":{"references":["var.credit_types_treatment"]},"labels":{"references":["var.labels"]},"projects":{"references":["local.projects"]},"services":{"references":["local.services"]}}],"display_name":{"references":["local.display_name"]}},"schema_version":1,"count_expression":{"references":["var.create_budget"]}},{"address":"data.google_project.project","mode":"data","type":"google_project","name":"project","provider_config_key":"google","expressions":{"project_id":{"references":["var.projects","count.index"]}},"schema_version":0,"count_expression":{"references":["var.create_budget","var.projects"]},"depends_on":["var.projects"]}],"variables":{"alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"amount":{"description":"The amount to use as the budget"},"billing_account":{"description":"ID of the billing account to set a budget on"},"calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"create_budget":{"default":true,"description":"If the budget should be created"},"credit_types_treatment":{"default":"INCLUDE_ALL_CREDITS","description":"Specifies how credits should be treated when determining spend for threshold calculations"},"custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"projects":{"description":"The project ids to include in this budget. If empty budget will include all projects"},"services":{"default":null,"description":"A list of services ids to be included in the budget. If omitted, all services will be included in the budget. Service ids can be found at https://cloud.google.com/skus/"}}}},"essential_contacts":{"source":"./modules/essential_contacts","expressions":{"essential_contacts":{"references":["var.essential_contacts"]},"language_tag":{"references":["var.language_tag"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"essential_contacts":{"expression":{"references":["google_essential_contacts_contact.contact"]},"description":"Essential Contact resources created"},"project_id":{"expression":{"references":["var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_essential_contacts_contact.contact","mode":"managed","type":"google_essential_contacts_contact","name":"contact","provider_config_key":"google","expressions":{"email":{"references":["each.key"]},"language_tag":{"references":["var.language_tag"]},"notification_category_subscriptions":{"references":["each.value"]},"parent":{"references":["var.project_id"]}},"schema_version":0,"for_each_expression":{"references":["var.essential_contacts"]}}],"variables":{"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"language_tag":{"description":"Language code to be used for essential contacts notifiactions"},"project_id":{"description":"The GCP project you want to send Essential Contacts notifications for"}}}},"gsuite_group":{"source":"./modules/gsuite_group","expressions":{"domain":{"references":["var.domain"]},"name":{"references":["var.group_name"]},"org_id":{"references":["var.org_id"]}},"module":{"outputs":{"domain":{"expression":{"references":["local.domain"]},"description":"The domain of the group's organization."},"email":{"expression":{"references":["local.email"]},"description":"The email address of the group."},"name":{"expression":{"references":["var.name"]},"description":"The username portion of the email address of the group."}},"resources":[{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"organization":{"references":["var.org_id"]}},"schema_version":0,"count_expression":{"references":["var.domain","var.name"]}}],"variables":{"domain":{"default":"","description":"The domain name"},"name":{"default":"","description":"The name of the group."},"org_id":{"default":null,"description":"The organization ID."}}}},"project-factory":{"source":"./modules/core_project_factory","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["var.activate_apis"]},"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"bucket_force_destroy":{"references":["var.bucket_force_destroy"]},"bucket_labels":{"references":["var.bucket_labels"]},"bucket_location":{"references":["var.bucket_location"]},"bucket_name":{"references":["var.bucket_name"]},"bucket_pap":{"references":["var.bucket_pap"]},"bucket_project":{"references":["var.bucket_project"]},"bucket_ula":{"references":["var.bucket_ula"]},"bucket_versioning":{"references":["var.bucket_versioning"]},"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"create_project_sa":{"references":["var.create_project_sa"]},"default_network_tier":{"references":["var.default_network_tier"]},"default_service_account":{"references":["var.default_service_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"enable_shared_vpc_host_project":{"references":["var.enable_shared_vpc_host_project"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"folder_id":{"references":["var.folder_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"group_email":{"references":["module.gsuite_group.email","module.gsuite_group"]},"group_role":{"references":["var.group_role"]},"labels":{"references":["var.labels"]},"lien":{"references":["var.lien"]},"manage_group":{"references":["var.group_name"]},"name":{"references":["var.name"]},"org_id":{"references":["var.folder_id","var.org_id"]},"project_id":{"references":["var.project_id"]},"project_sa_name":{"references":["var.project_sa_name"]},"random_project_id":{"references":["var.random_project_id"]},"random_project_id_length":{"references":["var.random_project_id_length"]},"sa_role":{"references":["var.sa_role"]},"shared_vpc":{"references":["var.svpc_host_project_id"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]},"tag_binding_values":{"references":["var.tag_binding_values"]},"usage_bucket_name":{"references":["var.usage_bucket_name"]},"usage_bucket_prefix":{"references":["var.usage_bucket_prefix"]},"vpc_service_control_attach_dry_run":{"references":["var.vpc_service_control_attach_dry_run"]},"vpc_service_control_attach_enabled":{"references":["var.vpc_service_control_attach_enabled"]},"vpc_service_control_perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"vpc_service_control_sleep_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["local.api_s_account"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["local.api_s_account_fmt"]},"description":"API service account email formatted for terraform use"},"enabled_api_identities":{"expression":{"references":["module.project_services.enabled_api_identities","module.project_services"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project_services.enabled_apis","module.project_services"]},"description":"Enabled APIs in the project"},"project_bucket_name":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"The name of the projec's bucket"},"project_bucket_self_link":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project_services.project_id","module.project_services"]},"depends_on":["module.project_services","google_project.main","google_compute_shared_vpc_service_project.shared_vpc_attachment","google_compute_shared_vpc_host_project.shared_vpc_host"],"description":"ID of the project"},"project_name":{"expression":{"references":["google_project.main.name","google_project.main"]},"description":"Name of the project"},"project_number":{"expression":{"references":["google_project.main.number","google_project.main"]},"depends_on":["module.project_services"],"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].display_name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].account_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].unique_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["google_tags_tag_binding.bindings"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["google_project_usage_export_bucket.usage_report_export[0]","google_project_usage_export_bucket.usage_report_export"]},"description":"GCE usage reports bucket"}},"resources":[{"address":"google_access_context_manager_service_perimeter_dry_run_resource.service_perimeter_attachment_dry_run","mode":"managed","type":"google_access_context_manager_service_perimeter_dry_run_resource","name":"service_perimeter_attachment_dry_run","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_dry_run","var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_access_context_manager_service_perimeter_resource.service_perimeter_attachment","mode":"managed","type":"google_access_context_manager_service_perimeter_resource","name":"service_perimeter_attachment","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_compute_project_cloud_armor_tier.cloud_armor_tier_config","mode":"managed","type":"google_compute_project_cloud_armor_tier","name":"cloud_armor_tier_config","provider_config_key":"google","expressions":{"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.cloud_armor_tier"]}},{"address":"google_compute_project_default_network_tier.default","mode":"managed","type":"google_compute_project_default_network_tier","name":"default","provider_config_key":"google","expressions":{"network_tier":{"references":["var.default_network_tier"]},"project":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.default_network_tier"]}},{"address":"google_compute_shared_vpc_host_project.shared_vpc_host","mode":"managed","type":"google_compute_shared_vpc_host_project","name":"shared_vpc_host","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_host_project"]},"depends_on":["module.project_services"]},{"address":"google_compute_shared_vpc_service_project.shared_vpc_attachment","mode":"managed","type":"google_compute_shared_vpc_service_project","name":"shared_vpc_attachment","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"host_project":{"references":["var.shared_vpc"]},"service_project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_service_project"]},"depends_on":["time_sleep.wait_5_seconds[0]","module.project_services"]},{"address":"google_compute_subnetwork_iam_member.apis_service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"apis_service_account_role_to_vpc_subnets","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.api_s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.shared_vpc_subnets"]},"depends_on":["module.project_services"]},{"address":"google_compute_subnetwork_iam_member.group_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"group_role_to_vpc_subnets","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.manage_group","var.shared_vpc_subnets"]}},{"address":"google_compute_subnetwork_iam_member.service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_account_role_to_vpc_subnets","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.create_project_sa","var.shared_vpc_subnets"]}},{"address":"google_project.main","mode":"managed","type":"google_project","name":"main","provider_config_key":"google","expressions":{"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"folder_id":{"references":["local.project_folder_id"]},"labels":{"references":["var.labels"]},"name":{"references":["var.name"]},"org_id":{"references":["local.project_org_id"]},"project_id":{"references":["local.temp_project_id"]}},"schema_version":1},{"address":"google_project_default_service_accounts.default_service_accounts","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","provider_config_key":"google","expressions":{"action":{"references":["var.default_service_account"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"restore_policy":{"constant_value":"REVERT_AND_IGNORE_FAILURE"}},"schema_version":0,"count_expression":{"references":["var.default_service_account"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.controlling_group_vpc_membership","mode":"managed","type":"google_project_iam_member","name":"controlling_group_vpc_membership","provider_config_key":"google","expressions":{"member":{"references":["local.shared_vpc_users","count.index"]},"project":{"references":["var.shared_vpc"]},"role":{"constant_value":"roles/compute.networkUser"}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","local.shared_vpc_users_length"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.default_service_account_membership","mode":"managed","type":"google_project_iam_member","name":"default_service_account_membership","provider_config_key":"google","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.sa_role"]}},"schema_version":0,"count_expression":{"references":["var.sa_role","var.create_project_sa"]}},{"address":"google_project_iam_member.gsuite_group_role","mode":"managed","type":"google_project_iam_member","name":"gsuite_group_role","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.group_role"]}},"schema_version":0,"count_expression":{"references":["var.manage_group"]}},{"address":"google_project_service.enable_access_context_manager","mode":"managed","type":"google_project_service","name":"enable_access_context_manager","provider_config_key":"google","expressions":{"project":{"references":["google_project.main.number","google_project.main"]},"service":{"constant_value":"accesscontextmanager.googleapis.com"}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]}},{"address":"google_project_usage_export_bucket.usage_report_export","mode":"managed","type":"google_project_usage_export_bucket","name":"usage_report_export","provider_config_key":"google","expressions":{"bucket_name":{"references":["var.usage_bucket_name"]},"prefix":{"references":["var.usage_bucket_prefix","var.usage_bucket_prefix","google_project.main.project_id","google_project.main"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.usage_bucket_name"]},"depends_on":["module.project_services"]},{"address":"google_resource_manager_lien.lien","mode":"managed","type":"google_resource_manager_lien","name":"lien","provider_config_key":"google","expressions":{"origin":{"constant_value":"project-factory"},"parent":{"references":["google_project.main.number","google_project.main"]},"reason":{"constant_value":"Project Factory lien"},"restrictions":{"constant_value":["resourcemanager.projects.delete"]}},"schema_version":0,"count_expression":{"references":["var.lien"]}},{"address":"google_service_account.default_service_account","mode":"managed","type":"google_service_account","name":"default_service_account","provider_config_key":"google","expressions":{"account_id":{"references":["var.project_sa_name"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["var.name"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.create_project_sa"]}},{"address":"google_service_account_iam_member.service_account_grant_to_group","mode":"managed","type":"google_service_account_iam_member","name":"service_account_grant_to_group","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["google_project.main.project_id","google_project.main","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]}},"schema_version":0,"count_expression":{"references":["var.manage_group","var.create_project_sa"]}},{"address":"google_storage_bucket.project_bucket","mode":"managed","type":"google_storage_bucket","name":"project_bucket","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"force_destroy":{"references":["var.bucket_force_destroy"]},"labels":{"references":["var.bucket_labels"]},"location":{"references":["var.bucket_location"]},"name":{"references":["local.project_bucket_name"]},"project":{"references":["var.bucket_project","local.base_project_id","google_project.main.project_id","google_project.main","var.bucket_project"]},"public_access_prevention":{"references":["var.bucket_pap"]},"uniform_bucket_level_access":{"references":["var.bucket_ula"]},"versioning":[{"enabled":{"references":["var.bucket_versioning"]}}]},"schema_version":3,"count_expression":{"references":["local.create_bucket"]}},{"address":"google_storage_bucket_iam_member.api_s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"api_s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.api_s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket"]},"depends_on":["module.project_services"]},{"address":"google_storage_bucket_iam_member.group_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"group_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.manage_group"]}},{"address":"google_storage_bucket_iam_member.s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.create_project_sa"]}},{"address":"google_tags_tag_binding.bindings","mode":"managed","type":"google_tags_tag_binding","name":"bindings","provider_config_key":"google","expressions":{"parent":{"references":["google_project.main.number","google_project.main"]},"tag_value":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.tag_binding_values"]}},{"address":"random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_config_key":"module.seed_bootstrap.module.seed_project.module.project-factory:random","expressions":{"byte_length":{"constant_value":2}},"schema_version":0},{"address":"random_string.random_project_id_suffix","mode":"managed","type":"random_string","name":"random_project_id_suffix","provider_config_key":"module.seed_bootstrap.module.seed_project.module.project-factory:random","expressions":{"length":{"references":["var.random_project_id_length"]},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2,"count_expression":{"references":["local.use_random_string"]}},{"address":"time_sleep.wait_5_seconds","mode":"managed","type":"time_sleep","name":"wait_5_seconds","provider_config_key":"module.seed_bootstrap.module.seed_project.module.project-factory:time","expressions":{"create_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]},"depends_on":["google_access_context_manager_service_perimeter_resource.service_perimeter_attachment[0]","google_project_service.enable_access_context_manager[0]"]}],"module_calls":{"project_services":{"source":"../project_services","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["local.activate_apis"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"project_id":{"references":["google_project.main.project_id","google_project.main"]}},"module":{"outputs":{"enabled_api_identities":{"expression":{"references":["google_project_service_identity.project_service_identities"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["google_project_service.project_services"]},"description":"Enabled APIs in the project"},"project_id":{"expression":{"references":["google_project_service.project_services","var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_project_iam_member.project_service_identity_roles","mode":"managed","type":"google_project_iam_member","name":"project_service_identity_roles","provider_config_key":"google","expressions":{"member":{"references":["each.value.email","each.value"]},"project":{"references":["var.project_id"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.add_service_roles"]}},{"address":"google_project_service.project_services","mode":"managed","type":"google_project_service","name":"project_services","provider_config_key":"google","expressions":{"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_on_destroy":{"references":["var.disable_services_on_destroy"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.services"]}},{"address":"google_project_service_identity.project_service_identities","mode":"managed","type":"google_project_service_identity","name":"project_service_identities","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"project":{"references":["var.project_id"]},"service":{"references":["each.value.api","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.activate_api_identities"]}},{"address":"data.google_compute_default_service_account.default","mode":"data","type":"google_compute_default_service_account","name":"default","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.activate_compute_identity"]}}],"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":[],"description":"The list of apis to activate within the project"},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_dependent_services"},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_on_destroy"},"enable_apis":{"default":true,"description":"Whether to actually enable the APIs. If false, this module is a no-op."},"project_id":{"description":"The GCP project you want to enable APIs on"}}}}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`. Use for services supported by `gcloud beta services identity create`\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false."},"enable_shared_vpc_service_project":{"description":"If this project should be attached to a shared VPC. If true, you must set shared_vpc variable."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"group_email":{"default":"","description":"The email address of a group to control the project by being assigned group_role."},"group_role":{"default":"","description":"The role to give the controlling group (group_name) over the project."},"labels":{"default":{},"description":"Map of labels for project"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"manage_group":{"default":false,"description":"A toggle to indicate if a G Suite group should be managed."},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}}},"quotas":{"source":"./modules/quota_manager","expressions":{"consumer_quotas":{"references":["var.consumer_quotas"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"quota_overrides":{"expression":{"references":["google_service_usage_consumer_quota_override.override"]},"description":"The server-generated names of the quota override."}},"resources":[{"address":"google_service_usage_consumer_quota_override.override","mode":"managed","type":"google_service_usage_consumer_quota_override","name":"override","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"dimensions":{"references":["each.value.dimensions","each.value"]},"force":{"constant_value":true},"limit":{"references":["each.value.limit","each.value"]},"metric":{"references":["each.value.metric","each.value"]},"override_value":{"references":["each.value.value","each.value"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value.service","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.consumer_quotas"]}}],"variables":{"consumer_quotas":{"description":"The quotas configuration you want to override for the project."},"project_id":{"description":"The GCP project where you want to manage the consumer quotas"}}}},"shared_vpc_access":{"source":"./modules/shared_vpc_access","expressions":{"active_apis":{"references":["var.activate_apis","var.activate_api_identities"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"grant_services_security_admin_role":{"references":["var.grant_services_security_admin_role"]},"host_project_id":{"references":["var.svpc_host_project_id"]},"lookup_project_numbers":{"constant_value":false},"service_project_id":{"references":["module.project-factory.project_id","module.project-factory"]},"service_project_number":{"references":["module.project-factory.project_number","module.project-factory"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]}},"module":{"outputs":{"active_api_service_accounts":{"expression":{"references":["local.active_apis"]},"description":"List of active API service accounts in the service project."},"project_id":{"expression":{"references":["var.service_project_id"]},"depends_on":["google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","google_project_iam_member.gke_host_agent","google_project_iam_member.service_shared_vpc_user"],"description":"Service project ID."}},"resources":[{"address":"google_compute_subnetwork_iam_member.cloudservices_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"cloudservices_shared_vpc_subnet_users","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.service_project_number"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role","local.subnetwork_api"]}},{"address":"google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_shared_vpc_subnet_users","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.apis","local.subnetwork_api","count.index"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"references":["local.apis","local.subnetwork_api","count.index"]},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","local.subnetwork_api"]}},{"address":"google_project_iam_member.composer_host_agent","mode":"managed","type":"google_project_iam_member","name":"composer_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"composer.googleapis.com\"].service_account","local.apis[\"composer.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/composer.sharedVpcAgent"}},"schema_version":0,"count_expression":{"references":["local.composer_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datasfusion_network_viewer","mode":"managed","type":"google_project_iam_member","name":"datasfusion_network_viewer","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datafusion.googleapis.com\"].service_account","local.apis[\"datafusion.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkViewer"}},"schema_version":0,"count_expression":{"references":["local.datafusion_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datastream_network_admin","mode":"managed","type":"google_project_iam_member","name":"datastream_network_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datastream.googleapis.com\"].service_account","local.apis[\"datastream.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkAdmin"}},"schema_version":0,"count_expression":{"references":["local.datastream_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_network_admin_role"]}},{"address":"google_project_iam_member.gke_host_agent","mode":"managed","type":"google_project_iam_member","name":"gke_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/container.hostServiceAgentUser"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.gke_security_admin","mode":"managed","type":"google_project_iam_member","name":"gke_security_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.securityAdmin"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_security_admin_role"]}},{"address":"google_project_iam_member.service_shared_vpc_user","mode":"managed","type":"google_project_iam_member","name":"service_shared_vpc_user","provider_config_key":"google","expressions":{"member":{"references":["local.apis","each.value"]},"project":{"references":["var.host_project_id"]},"role":{"references":["local.apis","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.shared_vpc_subnets","var.enable_shared_vpc_service_project","var.grant_network_role","local.active_apis"]}},{"address":"data.google_project.service_project","mode":"data","type":"google_project","name":"service_project","provider_config_key":"google","expressions":{"project_id":{"references":["var.service_project_id"]}},"schema_version":0,"count_expression":{"references":["var.lookup_project_numbers"]}}],"variables":{"active_apis":{"default":[],"description":"The list of active apis on the service project. If api is not active this module will not try to activate it"},"enable_shared_vpc_service_project":{"description":"Flag set if SVPC enabled"},"grant_network_role":{"default":true,"description":"Whether or not to grant service agents the network roles on the host project"},"grant_services_network_admin_role":{"default":false,"description":"Whether or not to grant Datastream Service acount the Network Admin role on the host project so it can manage firewall rules"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"host_project_id":{"description":"The ID of the host project which hosts the shared VPC"},"lookup_project_numbers":{"default":true,"description":"Whether to look up the project numbers from data sources. If false, `service_project_number` will be used instead."},"service_project_id":{"description":"The ID of the service project"},"service_project_number":{"default":null,"description":"Project number of the service project. Will be used if `lookup_service_project_number` is false."},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"}}},"depends_on":["module.project-factory.enabled_apis"]}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"budget_alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"budget_alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"budget_alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"budget_amount":{"default":null,"description":"The amount to use for a budget alert"},"budget_calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"budget_custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"budget_labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"budget_monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"consumer_quotas":{"default":[],"description":"The quotas configuration you want to override for the project."},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"domain":{"default":"","description":"The domain name (optional)."},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set svpc_host_project_id variable. Default is false."},"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"group_name":{"default":"","description":"A group to control the project by being assigned group_role (defaults to project editor)"},"group_role":{"default":"roles/editor","description":"The role to give the controlling group (group_name) over the project (defaults to project editor)"},"labels":{"default":{},"description":"Map of labels for project"},"language_tag":{"default":"en-US","description":"Language code to be used for essential contacts notifications"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"svpc_host_project_id":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}},"version_constraint":"~\u003e 18.0"}},"variables":{"activate_apis":{"default":["serviceusage.googleapis.com","servicenetworking.googleapis.com","compute.googleapis.com","logging.googleapis.com","bigquery.googleapis.com","cloudresourcemanager.googleapis.com","cloudbilling.googleapis.com","iam.googleapis.com","admin.googleapis.com","appengine.googleapis.com","storage-api.googleapis.com","monitoring.googleapis.com"],"description":"List of APIs to enable in the seed project."},"billing_account":{"description":"The ID of the billing account to associate projects with."},"create_terraform_sa":{"default":true,"description":"If the Terraform service account should be created."},"default_region":{"default":"us-central1","description":"Default region to create resources where applicable."},"encrypt_gcs_bucket_tfstate":{"default":false,"description":"Encrypt bucket used for storing terraform state files in seed project."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"force_destroy":{"default":false,"description":"If supplied, the state bucket will be deleted even while containing objects."},"grant_billing_user":{"default":true,"description":"Grant roles/billing.user role to CFT service account"},"group_billing_admins":{"description":"Google Group for GCP Billing Administrators"},"group_org_admins":{"description":"Google Group for GCP Organization Administrators"},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\"]"},"key_rotation_period":{"default":null,"description":"The rotation period of the key."},"kms_prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"org_admins_org_iam_permissions":{"default":["roles/billing.user","roles/resourcemanager.organizationAdmin"],"description":"List of permissions granted to the group supplied in group_org_admins variable across the GCP organization."},"org_id":{"description":"GCP Organization ID"},"org_project_creators":{"default":[],"description":"Additional list of members to have project creator role accross the organization. Prefix of group: user: or serviceAccount: is required."},"parent_folder":{"default":"","description":"GCP parent folder ID in the form folders/{id}"},"project_auto_create_network":{"default":false,"description":"Create the default network for the project created."},"project_deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project created."},"project_id":{"default":"","description":"Custom project ID to use for project created. If not supplied, the default id is {project_prefix}-seed-{random suffix}."},"project_labels":{"default":{},"description":"Labels to apply to the project."},"project_prefix":{"default":"cft","description":"Name prefix to use for projects created."},"random_suffix":{"default":true,"description":"Appends a 4 character random suffix to project ID and GCS bucket name."},"sa_enable_impersonation":{"default":false,"description":"Allow org_admins group to impersonate service account \u0026 enable APIs required."},"sa_org_iam_permissions":{"default":["roles/billing.user","roles/compute.networkAdmin","roles/compute.xpnAdmin","roles/iam.securityAdmin","roles/iam.serviceAccountAdmin","roles/logging.configWriter","roles/orgpolicy.policyAdmin","roles/resourcemanager.folderAdmin","roles/resourcemanager.organizationViewer"],"description":"List of permissions granted to Terraform service account across the GCP organization."},"state_bucket_name":{"default":"","description":"Custom state bucket name. If not supplied, the default name is {project_prefix}-tfstate-{random suffix}."},"storage_bucket_labels":{"default":{},"description":"Labels to apply to the storage bucket."},"tf_service_account_id":{"default":"org-terraform","description":"ID of service account for terraform in seed project"},"tf_service_account_name":{"default":"CFT Organization Terraform Account","description":"Display name of service account for terraform in seed project"}}},"version_constraint":"~\u003e 11.0","depends_on":["module.required_group"]},"seed_project_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]},"parent_type":{"constant_value":"project"},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_seed_project"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"tf_cloud_builder":{"source":"terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_builder","expressions":{"bucket_name":{"references":["var.bucket_prefix","module.tf_source.cloudbuild_project_id","module.tf_source"]},"build_timeout":{"constant_value":"1200s"},"cb_logs_bucket_force_destroy":{"references":["var.bucket_force_destroy"]},"dockerfile_repo_uri":{"references":["module.tf_source.csr_repos","module.tf_source","local.cloudbuilder_repo"]},"enable_worker_pool":{"constant_value":true},"gar_repo_location":{"references":["var.default_region"]},"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"terraform_version":{"references":["local.terraform_version"]},"trigger_location":{"references":["var.default_region"]},"worker_pool_id":{"references":["module.tf_private_pool.private_worker_pool_id","module.tf_private_pool"]},"workflow_deletion_protection":{"references":["var.workflow_deletion_protection"]},"workflow_region":{"references":["var.default_region"]}},"module":{"outputs":{"artifact_repo":{"expression":{"references":["google_artifact_registry_repository.tf-image-repo.name","google_artifact_registry_repository.tf-image-repo"]},"description":"GAR Repo created to store TF Cloud Builder images"},"cloudbuild_sa":{"expression":{"references":["local.cloudbuild_sa"]},"description":"SA used by Cloud Build trigger"},"cloudbuild_trigger_id":{"expression":{"references":["google_cloudbuild_trigger.build_trigger.id","google_cloudbuild_trigger.build_trigger"]},"description":"Trigger used for building new TF Builder"},"scheduler_id":{"expression":{"references":["google_cloud_scheduler_job.trigger_workflow.id","google_cloud_scheduler_job.trigger_workflow"]},"description":"Scheduler ID for periodically triggering TF Builder build Workflow"},"workflow_id":{"expression":{"references":["google_workflows_workflow.builder.id","google_workflows_workflow.builder"]},"description":"Workflow ID for triggering new TF Builder build"},"workflow_sa":{"expression":{"references":["local.workflow_sa"]},"description":"SA used by Workflow for triggering new TF Builder build"}},"resources":[{"address":"google_artifact_registry_repository.tf-image-repo","mode":"managed","type":"google_artifact_registry_repository","name":"tf-image-repo","provider_config_key":"google-beta","expressions":{"description":{"constant_value":"Docker repository for Terraform runner images used by Cloud Build. Managed by Terraform."},"format":{"constant_value":"DOCKER"},"location":{"references":["var.gar_repo_location"]},"project":{"references":["var.project_id"]},"repository_id":{"references":["var.gar_repo_name"]}},"schema_version":0},{"address":"google_artifact_registry_repository_iam_member.push_images","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"push_images","provider_config_key":"google-beta","expressions":{"location":{"references":["google_artifact_registry_repository.tf-image-repo.location","google_artifact_registry_repository.tf-image-repo"]},"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["var.project_id"]},"repository":{"references":["google_artifact_registry_repository.tf-image-repo.name","google_artifact_registry_repository.tf-image-repo"]},"role":{"constant_value":"roles/artifactregistry.writer"}},"schema_version":0},{"address":"google_artifact_registry_repository_iam_member.workflow_list","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"workflow_list","provider_config_key":"google-beta","expressions":{"location":{"references":["google_artifact_registry_repository.tf-image-repo.location","google_artifact_registry_repository.tf-image-repo"]},"member":{"references":["local.workflow_sa"]},"project":{"references":["var.project_id"]},"repository":{"references":["google_artifact_registry_repository.tf-image-repo.name","google_artifact_registry_repository.tf-image-repo"]},"role":{"constant_value":"roles/artifactregistry.reader"}},"schema_version":0},{"address":"google_cloud_scheduler_job.trigger_workflow","mode":"managed","type":"google_cloud_scheduler_job","name":"trigger_workflow","provider_config_key":"google","expressions":{"description":{"constant_value":"Trigger workflow for TF Runner builds. Managed by Terraform."},"http_target":[{"http_method":{"constant_value":"POST"},"oauth_token":[{"scope":{"constant_value":"https://www.googleapis.com/auth/cloud-platform"},"service_account_email":{"references":["local.workflow_sa"]}}],"uri":{"references":["google_workflows_workflow.builder.id","google_workflows_workflow.builder"]}}],"name":{"references":["var.workflow_name"]},"project":{"references":["var.project_id"]},"region":{"references":["var.workflow_region"]},"schedule":{"references":["var.workflow_schedule"]},"time_zone":{"constant_value":"Etc/UTC"}},"schema_version":0},{"address":"google_cloudbuild_trigger.build_trigger","mode":"managed","type":"google_cloudbuild_trigger","name":"build_trigger","provider_config_key":"google","expressions":{"build":[{"images":{"references":["local.img_tags_subst"]},"logs_bucket":{"references":["module.bucket.bucket.url","module.bucket.bucket","module.bucket"]},"step":[{"args":{"references":["local.img_tags_subst"]},"dir":{"references":["var.dockerfile_repo_dir","var.dockerfile_repo_dir"]},"name":{"constant_value":"gcr.io/cloud-builders/docker"}},{"args":{"constant_value":["version"]},"name":{"references":["local.gar_uri"]}}],"timeout":{"references":["var.build_timeout"]}}],"description":{"constant_value":"Builds a Terraform runner image. Managed by Terraform."},"location":{"references":["var.trigger_location"]},"name":{"references":["var.trigger_name"]},"project":{"references":["var.project_id"]},"service_account":{"references":["local.cloudbuild_sa"]},"substitutions":{"references":["local.tags_subst"]}},"schema_version":2,"depends_on":["google_artifact_registry_repository_iam_member.push_images","google_project_iam_member.logs_writer"]},{"address":"google_project_iam_member.invoke_workflow_scheduler","mode":"managed","type":"google_project_iam_member","name":"invoke_workflow_scheduler","provider_config_key":"google","expressions":{"member":{"references":["local.workflow_sa"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/workflows.invoker"}},"schema_version":0},{"address":"google_project_iam_member.logs_writer","mode":"managed","type":"google_project_iam_member","name":"logs_writer","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/logging.logWriter"}},"schema_version":0},{"address":"google_project_iam_member.trigger_builds","mode":"managed","type":"google_project_iam_member","name":"trigger_builds","provider_config_key":"google","expressions":{"member":{"references":["local.workflow_sa"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/cloudbuild.builds.editor"}},"schema_version":0},{"address":"google_service_account.cb_sa","mode":"managed","type":"google_service_account","name":"cb_sa","provider_config_key":"google","expressions":{"account_id":{"constant_value":"tf-cb-builder-sa"},"create_ignore_already_exists":{"constant_value":true},"display_name":{"constant_value":"SA for Terraform builder build trigger. Managed by Terraform."},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.cloudbuild_sa"]}},{"address":"google_service_account.workflow_sa","mode":"managed","type":"google_service_account","name":"workflow_sa","provider_config_key":"google","expressions":{"account_id":{"constant_value":"terraform-runner-workflow-sa"},"create_ignore_already_exists":{"constant_value":true},"display_name":{"constant_value":"SA for TF Builder Workflow. Managed by Terraform."},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.workflow_sa"]}},{"address":"google_service_account_iam_member.use_cb_sa","mode":"managed","type":"google_service_account_iam_member","name":"use_cb_sa","provider_config_key":"google","expressions":{"member":{"references":["local.workflow_sa"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["local.cloudbuild_sa"]}},"schema_version":0},{"address":"google_sourcerepo_repository_iam_member.member","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["local.source_repo_project"]},"repository":{"references":["local.source_repo_name"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0,"count_expression":{"references":["local.is_source_repo"]}},{"address":"google_storage_bucket_iam_member.member","mode":"managed","type":"google_storage_bucket_iam_member","name":"member","provider_config_key":"google","expressions":{"bucket":{"references":["module.bucket.bucket.self_link","module.bucket.bucket","module.bucket"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"google_workflows_workflow.builder","mode":"managed","type":"google_workflows_workflow","name":"builder","provider_config_key":"google","expressions":{"deletion_protection":{"references":["var.workflow_deletion_protection"]},"description":{"constant_value":"Workflow for triggering TF Runner builds. Managed by Terraform."},"name":{"references":["var.workflow_name"]},"project":{"references":["var.project_id"]},"region":{"references":["var.workflow_region"]},"service_account":{"references":["local.workflow_sa"]},"source_contents":{"references":["local.rendered_workflow_config"]}},"schema_version":1}],"module_calls":{"bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.cb_logs_bucket_force_destroy"]},"location":{"references":["var.gar_repo_location"]},"name":{"references":["local.log_bucket_name"]},"project_id":{"references":["var.project_id"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"}},"variables":{"bucket_name":{"default":"","description":"Custom bucket name for Cloud Build logs."},"build_timeout":{"default":"600s","description":"Amount of time the build should be allowed to run, to second granularity. Format is the number of seconds followed by s."},"cb_logs_bucket_force_destroy":{"default":false,"description":"When deleting the bucket for storing CloudBuild logs, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"cloudbuild_sa":{"default":"","description":"Custom SA email to be used by the CloudBuild trigger. Defaults to being created if empty."},"dockerfile_repo_dir":{"default":"","description":"The directory inside the repo where the Dockerfile is located. If empty defaults to repo root."},"dockerfile_repo_ref":{"default":"refs/heads/main","description":"The branch or tag to use. Use refs/heads/branchname for branches or refs/tags/tagname for tags."},"dockerfile_repo_type":{"default":"CLOUD_SOURCE_REPOSITORIES","description":"Type of repo"},"dockerfile_repo_uri":{"default":"","description":"The URI of the repo where the Dockerfile for Terraform builder is stored. If using Cloud Build Repositories (2nd Gen) this is the repository ID where the Dockerfile is stored. Repository ID Format is 'projects/{{project}}/locations/{{location}}/connections/{{parent_connection}}/repositories/{{name}}'"},"enable_worker_pool":{"default":false,"description":"Set to true to use a private worker pool in the Cloud Build Trigger."},"gar_repo_location":{"description":"Name of the location for the Google Artifact Repository."},"gar_repo_name":{"default":"tf-runners","description":"Name of the Google Artifact Repository where the Terraform builder images are stored."},"image_name":{"default":"terraform","description":"Name of the image for the Terraform builder."},"project_id":{"description":"GCP project for Cloud Build trigger,workflow and scheduler."},"terraform_version":{"default":"1.1.0","description":"The initial terraform version in semantic version format."},"trigger_location":{"description":"Location of the Cloud Build trigger building the Terraform builder. If using private pools should be the same location as the pool."},"trigger_name":{"default":"tf-cloud-builder-build","description":"Name of the Cloud Build trigger building the Terraform builder."},"use_cloudbuildv2_repository":{"default":false,"description":"Use Cloud Build repository (2nd gen)"},"worker_pool_id":{"default":"","description":"Custom private worker pool ID. Format: 'projects/PROJECT_ID/locations/REGION/workerPools/PRIVATE_POOL_ID'."},"workflow_deletion_protection":{"default":true,"description":"Whether Terraform will be prevented from destroying the workflow. When the field is set to true or unset in Terraform state, a `terraform apply` or `terraform destroy` that would delete the workflow will fail. When the field is set to false, deleting the workflow is allowed."},"workflow_name":{"default":"terraform-runner-workflow","description":"Name of the workflow managing builds."},"workflow_region":{"default":"us-central1","description":"The region of the workflow."},"workflow_sa":{"default":"","description":"Custom SA email to be used by the workflow. Defaults to being created if empty."},"workflow_schedule":{"default":"0 8 * * *","description":"The workflow frequency, in cron syntax"}}},"version_constraint":"~\u003e 11.0"},"tf_private_pool":{"source":"./modules/cb-private-pool","expressions":{"private_worker_pool":{"references":["var.default_region"]},"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"vpn_configuration":{"constant_value":{"enable_vpn":false}}},"module":{"outputs":{"peered_network_id":{"expression":{"references":["local.peered_network_id"]},"description":"The ID of the peered network."},"private_worker_pool_id":{"expression":{"references":["google_cloudbuild_worker_pool.private_pool.id","google_cloudbuild_worker_pool.private_pool"]},"description":"Private worker pool ID."},"worker_peered_ip_range":{"expression":{"references":["local.peered_ip_range"]},"description":"The IP range of the peered service network."},"worker_range_id":{"expression":{"references":["google_compute_global_address.worker_pool_range[0].id","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range"]},"description":"The worker IP range ID."}},"resources":[{"address":"google_cloudbuild_worker_pool.private_pool","mode":"managed","type":"google_cloudbuild_worker_pool","name":"private_pool","provider_config_key":"google","expressions":{"location":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"name":{"references":["local.private_pool_name"]},"project":{"references":["var.project_id"]},"worker_config":[{"disk_size_gb":{"references":["var.private_worker_pool.disk_size_gb","var.private_worker_pool"]},"machine_type":{"references":["var.private_worker_pool.machine_type","var.private_worker_pool"]},"no_external_ip":{"references":["var.private_worker_pool.no_external_ip","var.private_worker_pool"]}}]},"schema_version":0,"depends_on":["google_compute_global_address.worker_pool_range","google_service_networking_connection.worker_pool_conn"]},{"address":"google_compute_address.cloud_build_nat","mode":"managed","type":"google_compute_address","name":"cloud_build_nat","provider_config_key":"google","expressions":{"address_type":{"constant_value":"EXTERNAL"},"name":{"constant_value":"cloud-build-nat"},"network_tier":{"constant_value":"PREMIUM"},"project":{"references":["var.project_id"]},"region":{"constant_value":"us-central1"}},"schema_version":0},{"address":"google_compute_global_address.worker_pool_range","mode":"managed","type":"google_compute_global_address","name":"worker_pool_range","provider_config_key":"google","expressions":{"address":{"references":["var.private_worker_pool.peering_address","var.private_worker_pool"]},"address_type":{"constant_value":"INTERNAL"},"name":{"constant_value":"ga-b-cbpools-worker-pool-range"},"network":{"references":["local.peered_network_id"]},"prefix_length":{"references":["var.private_worker_pool.peering_prefix_length","var.private_worker_pool"]},"project":{"references":["var.project_id"]},"purpose":{"constant_value":"VPC_PEERING"}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]}},{"address":"google_compute_instance.vm-proxy","mode":"managed","type":"google_compute_instance","name":"vm-proxy","provider_config_key":"google","expressions":{"boot_disk":[{"initialize_params":[{"image":{"constant_value":"debian-cloud/debian-12"}}]}],"can_ip_forward":{"constant_value":true},"machine_type":{"constant_value":"e2-medium"},"metadata_startup_script":{"constant_value":"sysctl -w net.ipv4.ip_forward=1 \u0026\u0026 iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE"},"name":{"constant_value":"cloud-build-nat-vm"},"network_interface":[{"network":{"references":["local.peered_network_name"]},"subnetwork":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"subnetwork_project":{"references":["var.project_id"]}}],"project":{"references":["var.project_id"]},"service_account":[{"scopes":{"constant_value":["cloud-platform"]}}],"tags":{"constant_value":["direct-gateway-access","nat-gateway"]},"zone":{"constant_value":"us-central1-a"}},"schema_version":6,"depends_on":["google_compute_router_nat.cb-nat"]},{"address":"google_compute_network_peering_routes_config.peering_routes","mode":"managed","type":"google_compute_network_peering_routes_config","name":"peering_routes","provider_config_key":"google","expressions":{"export_custom_routes":{"constant_value":true},"import_custom_routes":{"constant_value":true},"network":{"references":["local.peered_network_name"]},"peering":{"references":["google_service_networking_connection.worker_pool_conn[0].peering","google_service_networking_connection.worker_pool_conn[0]","google_service_networking_connection.worker_pool_conn"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]}},{"address":"google_compute_route.direct-to-gateway","mode":"managed","type":"google_compute_route","name":"direct-to-gateway","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"0.0.0.0/1"},"name":{"constant_value":"direct-to-gateway-range1"},"network":{"references":["local.peered_network_name"]},"next_hop_gateway":{"constant_value":"default-internet-gateway"},"priority":{"constant_value":5},"project":{"references":["var.project_id"]},"tags":{"constant_value":["direct-gateway-access"]}},"schema_version":0},{"address":"google_compute_route.direct-to-gateway2","mode":"managed","type":"google_compute_route","name":"direct-to-gateway2","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"128.0.0.0/1"},"name":{"constant_value":"direct-to-gateway-range2"},"network":{"references":["local.peered_network_name"]},"next_hop_gateway":{"constant_value":"default-internet-gateway"},"priority":{"constant_value":5},"project":{"references":["var.project_id"]},"tags":{"constant_value":["direct-gateway-access"]}},"schema_version":0},{"address":"google_compute_route.through-nat","mode":"managed","type":"google_compute_route","name":"through-nat","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"0.0.0.0/1"},"name":{"constant_value":"through-nat-range1"},"network":{"references":["local.peered_network_name"]},"next_hop_instance":{"references":["google_compute_instance.vm-proxy.id","google_compute_instance.vm-proxy"]},"priority":{"constant_value":10},"project":{"references":["var.project_id"]}},"schema_version":0},{"address":"google_compute_route.through-nat2","mode":"managed","type":"google_compute_route","name":"through-nat2","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"128.0.0.0/1"},"name":{"constant_value":"through-nat-range2"},"network":{"references":["local.peered_network_name"]},"next_hop_instance":{"references":["google_compute_instance.vm-proxy.id","google_compute_instance.vm-proxy"]},"priority":{"constant_value":10},"project":{"references":["var.project_id"]}},"schema_version":0},{"address":"google_compute_router.cb-router","mode":"managed","type":"google_compute_router","name":"cb-router","provider_config_key":"google","expressions":{"name":{"constant_value":"cb-cloud-router"},"network":{"references":["local.peered_network_name"]},"project":{"references":["var.project_id"]},"region":{"constant_value":"us-central1"}},"schema_version":0},{"address":"google_compute_router_nat.cb-nat","mode":"managed","type":"google_compute_router_nat","name":"cb-nat","provider_config_key":"google","expressions":{"log_config":[{"enable":{"constant_value":true},"filter":{"constant_value":"ALL"}}],"name":{"constant_value":"cb-cloud-nat"},"nat_ip_allocate_option":{"constant_value":"AUTO_ONLY"},"project":{"references":["var.project_id"]},"region":{"references":["google_compute_router.cb-router.region","google_compute_router.cb-router"]},"router":{"references":["google_compute_router.cb-router.name","google_compute_router.cb-router"]},"source_subnetwork_ip_ranges_to_nat":{"constant_value":"ALL_SUBNETWORKS_ALL_IP_RANGES"}},"schema_version":0},{"address":"google_dns_policy.default_policy","mode":"managed","type":"google_dns_policy","name":"default_policy","provider_config_key":"google","expressions":{"enable_inbound_forwarding":{"constant_value":true},"enable_logging":{"constant_value":true},"name":{"constant_value":"dp-b-cbpools-default-policy"},"networks":[{"network_url":{"references":["module.peered_network[0].network_self_link","module.peered_network[0]"]}}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.create_peered_network","var.private_worker_pool"]}},{"address":"google_service_networking_connection.worker_pool_conn","mode":"managed","type":"google_service_networking_connection","name":"worker_pool_conn","provider_config_key":"google","expressions":{"network":{"references":["local.peered_network_id"]},"reserved_peering_ranges":{"references":["google_compute_global_address.worker_pool_range[0].name","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range"]},"service":{"constant_value":"servicenetworking.googleapis.com"}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_config_key":"random","expressions":{"length":{"constant_value":4},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2},{"address":"data.google_secret_manager_secret_version.psk","mode":"data","type":"google_secret_manager_secret_version","name":"psk","provider_config_key":"google","expressions":{"project":{"references":["var.vpn_configuration.psk_secret_project_id","var.vpn_configuration"]},"secret":{"references":["var.vpn_configuration.psk_secret_name","var.vpn_configuration"]}},"schema_version":0,"count_expression":{"references":["var.vpn_configuration.enable_vpn","var.vpn_configuration"]}}],"module_calls":{"firewall_rules":{"source":"terraform-google-modules/network/google//modules/firewall-rules","expressions":{"network_name":{"references":["local.peered_network_id"]},"project_id":{"references":["var.project_id"]},"rules":{"references":["local.peered_ip_range","google_compute_global_address.worker_pool_range[0].address","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range","google_compute_global_address.worker_pool_range[0].prefix_length","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range"]}},"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]},"module":{"outputs":{"firewall_rules":{"expression":{"references":["google_compute_firewall.rules"]},"description":"The created firewall rule resources"},"firewall_rules_ingress_egress":{"expression":{"references":["google_compute_firewall.rules_ingress_egress"]},"description":"The created firewall ingress/egress rule resources"}},"resources":[{"address":"google_compute_firewall.rules","mode":"managed","type":"google_compute_firewall","name":"rules","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","var.rules"]}},{"address":"google_compute_firewall.rules_ingress_egress","mode":"managed","type":"google_compute_firewall","name":"rules_ingress_egress","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","local.rules_all"]}}],"variables":{"egress_rules":{"default":[],"description":"List of egress rules. This will be ignored if variable 'rules' is non-empty"},"ingress_rules":{"default":[],"description":"List of ingress rules. This will be ignored if variable 'rules' is non-empty"},"network_name":{"description":"Name of the network this set of firewall rules applies to."},"project_id":{"description":"Project id of the project that holds the network."},"rules":{"default":[],"description":"This is DEPRICATED and available for backward compatiblity. Use ingress_rules and egress_rules variables. List of custom rule definitions"}}},"version_constraint":"~\u003e 10.0"},"peered_network":{"source":"terraform-google-modules/network/google","expressions":{"delete_default_internet_gateway_routes":{"constant_value":"true"},"network_name":{"references":["local.network_name"]},"project_id":{"references":["var.project_id"]},"subnets":{"references":["var.private_worker_pool.region","var.private_worker_pool","var.private_worker_pool.peered_network_subnet_ip","var.private_worker_pool","var.private_worker_pool.region","var.private_worker_pool","var.vpc_flow_logs.aggregation_interval","var.vpc_flow_logs","var.vpc_flow_logs.flow_sampling","var.vpc_flow_logs","var.vpc_flow_logs.metadata","var.vpc_flow_logs","var.vpc_flow_logs.metadata_fields","var.vpc_flow_logs","var.vpc_flow_logs.filter_expr","var.vpc_flow_logs"]}},"count_expression":{"references":["var.private_worker_pool.create_peered_network","var.private_worker_pool"]},"module":{"outputs":{"network":{"expression":{"references":["module.vpc"]},"description":"The created network"},"network_id":{"expression":{"references":["module.vpc.network_id","module.vpc"]},"description":"The ID of the VPC being created"},"network_name":{"expression":{"references":["module.vpc.network_name","module.vpc"]},"description":"The name of the VPC being created"},"network_self_link":{"expression":{"references":["module.vpc.network_self_link","module.vpc"]},"description":"The URI of the VPC being created"},"project_id":{"expression":{"references":["module.vpc.project_id","module.vpc"]},"description":"VPC project id"},"route_names":{"expression":{"references":["module.routes.routes","module.routes"]},"description":"The route names associated with this VPC"},"subnets":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"A map with keys of form subnet_region/subnet_name and values being the outputs of the google_compute_subnetwork resources used to create corresponding subnets."},"subnets_flow_logs":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"Whether the subnets will have VPC flow logs enabled"},"subnets_ids":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The IDs of the subnets being created"},"subnets_ips":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The IPs and CIDRs of the subnets being created"},"subnets_names":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The names of the subnets being created"},"subnets_private_access":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"Whether the subnets will have access to Google API's without a public IP"},"subnets_regions":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The region where the subnets will be created"},"subnets_secondary_ranges":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The secondary ranges associated with these subnets"},"subnets_self_links":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The self-links of subnets being created"}},"module_calls":{"firewall_rules":{"source":"./modules/firewall-rules","expressions":{"egress_rules":{"references":["var.egress_rules"]},"ingress_rules":{"references":["var.ingress_rules"]},"network_name":{"references":["module.vpc.network_name","module.vpc"]},"project_id":{"references":["var.project_id"]},"rules":{"references":["local.rules"]}},"module":{"outputs":{"firewall_rules":{"expression":{"references":["google_compute_firewall.rules"]},"description":"The created firewall rule resources"},"firewall_rules_ingress_egress":{"expression":{"references":["google_compute_firewall.rules_ingress_egress"]},"description":"The created firewall ingress/egress rule resources"}},"resources":[{"address":"google_compute_firewall.rules","mode":"managed","type":"google_compute_firewall","name":"rules","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","var.rules"]}},{"address":"google_compute_firewall.rules_ingress_egress","mode":"managed","type":"google_compute_firewall","name":"rules_ingress_egress","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","local.rules_all"]}}],"variables":{"egress_rules":{"default":[],"description":"List of egress rules. This will be ignored if variable 'rules' is non-empty"},"ingress_rules":{"default":[],"description":"List of ingress rules. This will be ignored if variable 'rules' is non-empty"},"network_name":{"description":"Name of the network this set of firewall rules applies to."},"project_id":{"description":"Project id of the project that holds the network."},"rules":{"default":[],"description":"This is DEPRICATED and available for backward compatiblity. Use ingress_rules and egress_rules variables. List of custom rule definitions"}}}},"routes":{"source":"./modules/routes","expressions":{"module_depends_on":{"references":["module.subnets.subnets","module.subnets"]},"network_name":{"references":["module.vpc.network_name","module.vpc"]},"project_id":{"references":["var.project_id"]},"routes":{"references":["var.routes"]}},"module":{"outputs":{"routes":{"expression":{"references":["google_compute_route.route"]},"description":"The created routes resources"}},"resources":[{"address":"google_compute_route.route","mode":"managed","type":"google_compute_route","name":"route","provider_config_key":"google","expressions":{"description":{"references":["each.value"]},"dest_range":{"references":["each.value"]},"name":{"references":["each.key"]},"network":{"references":["var.network_name"]},"next_hop_gateway":{"references":["each.value"]},"next_hop_ilb":{"references":["each.value"]},"next_hop_instance":{"references":["each.value"]},"next_hop_instance_zone":{"references":["each.value"]},"next_hop_ip":{"references":["each.value"]},"next_hop_vpn_tunnel":{"references":["each.value"]},"priority":{"references":["each.value"]},"project":{"references":["var.project_id"]},"tags":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.routes"]},"depends_on":["var.module_depends_on"]}],"variables":{"module_depends_on":{"default":[],"description":"List of modules or resources this module depends on."},"network_name":{"description":"The name of the network where routes will be created"},"project_id":{"description":"The ID of the project where the routes will be created"},"routes":{"default":[],"description":"List of routes being created in this VPC"}}}},"subnets":{"source":"./modules/subnets","expressions":{"network_name":{"references":["module.vpc.network_name","module.vpc"]},"project_id":{"references":["var.project_id"]},"secondary_ranges":{"references":["var.secondary_ranges"]},"subnets":{"references":["var.subnets"]}},"module":{"outputs":{"subnets":{"expression":{"references":["google_compute_subnetwork.subnetwork"]},"description":"The created subnet resources"}},"resources":[{"address":"google_compute_subnetwork.subnetwork","mode":"managed","type":"google_compute_subnetwork","name":"subnetwork","provider_config_key":"google","expressions":{"description":{"references":["each.value"]},"ip_cidr_range":{"references":["each.value.subnet_ip","each.value"]},"ipv6_access_type":{"references":["each.value"]},"name":{"references":["each.value.subnet_name","each.value"]},"network":{"references":["var.network_name"]},"private_ip_google_access":{"references":["each.value"]},"private_ipv6_google_access":{"references":["each.value"]},"project":{"references":["var.project_id"]},"purpose":{"references":["each.value"]},"region":{"references":["each.value.subnet_region","each.value"]},"role":{"references":["each.value"]},"stack_type":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.subnets"]}}],"variables":{"network_name":{"description":"The name of the network where subnets will be created"},"project_id":{"description":"The ID of the project where subnets will be created"},"secondary_ranges":{"default":{},"description":"Secondary ranges that will be used in some of the subnets"},"subnets":{"description":"The list of subnets being created"}}}},"vpc":{"source":"./modules/vpc","expressions":{"auto_create_subnetworks":{"references":["var.auto_create_subnetworks"]},"delete_default_internet_gateway_routes":{"references":["var.delete_default_internet_gateway_routes"]},"description":{"references":["var.description"]},"enable_ipv6_ula":{"references":["var.enable_ipv6_ula"]},"internal_ipv6_range":{"references":["var.internal_ipv6_range"]},"mtu":{"references":["var.mtu"]},"network_firewall_policy_enforcement_order":{"references":["var.network_firewall_policy_enforcement_order"]},"network_name":{"references":["var.network_name"]},"network_profile":{"references":["var.network_profile"]},"project_id":{"references":["var.project_id"]},"routing_mode":{"references":["var.routing_mode"]},"shared_vpc_host":{"references":["var.shared_vpc_host"]}},"module":{"outputs":{"network":{"expression":{"references":["google_compute_network.network"]},"description":"The VPC resource being created"},"network_id":{"expression":{"references":["google_compute_network.network.id","google_compute_network.network"]},"description":"The ID of the VPC being created"},"network_name":{"expression":{"references":["google_compute_network.network.name","google_compute_network.network"]},"description":"The name of the VPC being created"},"network_self_link":{"expression":{"references":["google_compute_network.network.self_link","google_compute_network.network"]},"description":"The URI of the VPC being created"},"project_id":{"expression":{"references":["var.shared_vpc_host","google_compute_shared_vpc_host_project.shared_vpc_host","google_compute_shared_vpc_host_project.shared_vpc_host[0].project","google_compute_shared_vpc_host_project.shared_vpc_host[0]","google_compute_shared_vpc_host_project.shared_vpc_host","google_compute_network.network.project","google_compute_network.network"]},"description":"VPC project id"}},"resources":[{"address":"google_compute_network.network","mode":"managed","type":"google_compute_network","name":"network","provider_config_key":"google-beta","expressions":{"auto_create_subnetworks":{"references":["var.auto_create_subnetworks"]},"delete_default_routes_on_create":{"references":["var.delete_default_internet_gateway_routes"]},"description":{"references":["var.description"]},"enable_ula_internal_ipv6":{"references":["var.enable_ipv6_ula"]},"internal_ipv6_range":{"references":["var.internal_ipv6_range"]},"mtu":{"references":["var.mtu"]},"name":{"references":["var.network_name"]},"network_firewall_policy_enforcement_order":{"references":["var.network_firewall_policy_enforcement_order"]},"network_profile":{"references":["var.network_profile"]},"project":{"references":["var.project_id"]},"routing_mode":{"references":["var.routing_mode"]}},"schema_version":0},{"address":"google_compute_shared_vpc_host_project.shared_vpc_host","mode":"managed","type":"google_compute_shared_vpc_host_project","name":"shared_vpc_host","provider_config_key":"google-beta","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.shared_vpc_host"]},"depends_on":["google_compute_network.network"]}],"variables":{"auto_create_subnetworks":{"default":false,"description":"When set to true, the network is created in 'auto subnet mode' and it will create a subnet for each region automatically across the 10.128.0.0/9 address range. When set to false, the network is created in 'custom subnet mode' so the user can explicitly connect subnetwork resources."},"delete_default_internet_gateway_routes":{"default":false,"description":"If set, ensure that all routes within the network specified whose names begin with 'default-route' and with a next hop of 'default-internet-gateway' are deleted"},"description":{"default":"","description":"An optional description of this resource. The resource must be recreated to modify this field."},"enable_ipv6_ula":{"default":false,"description":"Enabled IPv6 ULA, this is a permenant change and cannot be undone! (default 'false')"},"internal_ipv6_range":{"default":null,"description":"When enabling IPv6 ULA, optionally, specify a /48 from fd20::/20 (default null)"},"mtu":{"default":0,"description":"The network MTU (If set to 0, meaning MTU is unset - defaults to '1460'). Recommended values: 1460 (default for historic reasons), 1500 (Internet default), or 8896 (for Jumbo packets). Allowed are all values in the range 1300 to 8896, inclusively."},"network_firewall_policy_enforcement_order":{"default":null,"description":"Set the order that Firewall Rules and Firewall Policies are evaluated. Valid values are `BEFORE_CLASSIC_FIREWALL` and `AFTER_CLASSIC_FIREWALL`. (default null or equivalent to `AFTER_CLASSIC_FIREWALL`)"},"network_name":{"description":"The name of the network being created"},"network_profile":{"default":null,"description":"\"A full or partial URL of the network profile to apply to this network.\nThis field can be set only at resource creation time. For example, the\nfollowing are valid URLs:\n * https://www.googleapis.com/compute/beta/projects/{projectId}/global/networkProfiles/{network_profile_name}\n * projects/{projectId}/global/networkProfiles/{network_profile_name}\n"},"project_id":{"description":"The ID of the project where this VPC will be created"},"routing_mode":{"default":"GLOBAL","description":"The network routing mode (default 'GLOBAL')"},"shared_vpc_host":{"default":false,"description":"Makes this project a Shared VPC host if 'true' (default 'false')"}}}}},"variables":{"auto_create_subnetworks":{"default":false,"description":"When set to true, the network is created in 'auto subnet mode' and it will create a subnet for each region automatically across the 10.128.0.0/9 address range. When set to false, the network is created in 'custom subnet mode' so the user can explicitly connect subnetwork resources."},"delete_default_internet_gateway_routes":{"default":false,"description":"If set, ensure that all routes within the network specified whose names begin with 'default-route' and with a next hop of 'default-internet-gateway' are deleted"},"description":{"default":"","description":"An optional description of this resource. The resource must be recreated to modify this field."},"egress_rules":{"default":[],"description":"List of egress rules. This will be ignored if variable 'rules' is non-empty"},"enable_ipv6_ula":{"default":false,"description":"Enabled IPv6 ULA, this is a permenant change and cannot be undone! (default 'false')"},"firewall_rules":{"default":[],"description":"This is DEPRICATED and available for backward compatiblity. Use ingress_rules and egress_rules variables. List of firewall rules"},"ingress_rules":{"default":[],"description":"List of ingress rules. This will be ignored if variable 'rules' is non-empty"},"internal_ipv6_range":{"default":null,"description":"When enabling IPv6 ULA, optionally, specify a /48 from fd20::/20 (default null)"},"mtu":{"default":0,"description":"The network MTU (If set to 0, meaning MTU is unset - defaults to '1460'). Recommended values: 1460 (default for historic reasons), 1500 (Internet default), or 8896 (for Jumbo packets). Allowed are all values in the range 1300 to 8896, inclusively."},"network_firewall_policy_enforcement_order":{"default":null,"description":"Set the order that Firewall Rules and Firewall Policies are evaluated. Valid values are `BEFORE_CLASSIC_FIREWALL` and `AFTER_CLASSIC_FIREWALL`. (default null or equivalent to `AFTER_CLASSIC_FIREWALL`)"},"network_name":{"description":"The name of the network being created"},"network_profile":{"default":null,"description":"\"A full or partial URL of the network profile to apply to this network.\nThis field can be set only at resource creation time. For example, the\nfollowing are valid URLs:\n * https://www.googleapis.com/compute/beta/projects/{projectId}/global/networkProfiles/{network_profile_name}\n * projects/{projectId}/global/networkProfiles/{network_profile_name}\n"},"project_id":{"description":"The ID of the project where this VPC will be created"},"routes":{"default":[],"description":"List of routes being created in this VPC"},"routing_mode":{"default":"GLOBAL","description":"The network routing mode (default 'GLOBAL')"},"secondary_ranges":{"default":{},"description":"Secondary ranges that will be used in some of the subnets"},"shared_vpc_host":{"default":false,"description":"Makes this project a Shared VPC host if 'true' (default 'false')"},"subnets":{"description":"The list of subnets being created"}}},"version_constraint":"~\u003e 10.0"},"vpn_ha_cb_to_onprem":{"source":"terraform-google-modules/vpn/google//modules/vpn_ha","expressions":{"name":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"network":{"references":["local.peered_network_id"]},"peer_external_gateway":{"references":["var.vpn_configuration.on_prem_public_ip_address0","var.vpn_configuration","var.vpn_configuration.on_prem_public_ip_address1","var.vpn_configuration"]},"project_id":{"references":["var.project_id"]},"region":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"router_advertise_config":{"references":["local.peered_ip_range"]},"router_asn":{"references":["var.vpn_configuration.router_asn","var.vpn_configuration"]},"tunnels":{"references":["var.vpn_configuration.tunnel0_bgp_peer_address","var.vpn_configuration","var.vpn_configuration.bgp_peer_asn","var.vpn_configuration","var.vpn_configuration.tunnel0_bgp_session_range","var.vpn_configuration","local.psk_secret_data","var.vpn_configuration.tunnel1_bgp_peer_address","var.vpn_configuration","var.vpn_configuration.bgp_peer_asn","var.vpn_configuration","var.vpn_configuration.tunnel1_bgp_session_range","var.vpn_configuration","local.psk_secret_data"]}},"count_expression":{"references":["var.vpn_configuration.enable_vpn","var.vpn_configuration"]},"module":{"outputs":{"external_gateway":{"expression":{"references":["var.peer_external_gateway","google_compute_external_vpn_gateway.external_gateway[0]","google_compute_external_vpn_gateway.external_gateway"]},"description":"External VPN gateway resource."},"gateway":{"expression":{"references":["google_compute_ha_vpn_gateway.ha_gateway"]},"description":"HA VPN gateway resource."},"name":{"expression":{"references":["local.vpn_gateway_self_link"]},"description":"VPN gateway name."},"random_secret":{"sensitive":true,"expression":{"references":["local.secret"]},"description":"Generated secret."},"router":{"expression":{"references":["var.router_name","google_compute_router.router[0]","google_compute_router.router"]},"description":"Router resource (only if auto-created)."},"router_name":{"expression":{"references":["local.router"]},"description":"Router name."},"self_link":{"expression":{"references":["local.vpn_gateway_self_link"]},"description":"HA VPN gateway self link."},"tunnel_names":{"expression":{"references":["var.tunnels","google_compute_vpn_tunnel.tunnels"]},"description":"VPN tunnel names."},"tunnel_self_links":{"sensitive":true,"expression":{"references":["var.tunnels","google_compute_vpn_tunnel.tunnels"]},"description":"VPN tunnel self links."},"tunnels":{"sensitive":true,"expression":{"references":["var.tunnels","google_compute_vpn_tunnel.tunnels"]},"description":"VPN tunnel resources."}},"resources":[{"address":"google_compute_external_vpn_gateway.external_gateway","mode":"managed","type":"google_compute_external_vpn_gateway","name":"external_gateway","provider_config_key":"google","expressions":{"description":{"references":["var.external_vpn_gateway_description"]},"labels":{"references":["var.labels"]},"name":{"references":["var.peer_external_gateway.name","var.peer_external_gateway","var.peer_external_gateway.name","var.peer_external_gateway","var.name"]},"project":{"references":["var.project_id"]},"redundancy_type":{"references":["var.peer_external_gateway.redundancy_type","var.peer_external_gateway"]}},"schema_version":0,"count_expression":{"references":["var.peer_external_gateway"]}},{"address":"google_compute_ha_vpn_gateway.ha_gateway","mode":"managed","type":"google_compute_ha_vpn_gateway","name":"ha_gateway","provider_config_key":"google","expressions":{"name":{"references":["var.name"]},"network":{"references":["var.network"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"stack_type":{"references":["var.stack_type"]}},"schema_version":1,"count_expression":{"references":["var.create_vpn_gateway"]}},{"address":"google_compute_router.router","mode":"managed","type":"google_compute_router","name":"router","provider_config_key":"google","expressions":{"bgp":[{"advertise_mode":{"references":["var.router_advertise_config","var.router_advertise_config.mode","var.router_advertise_config"]},"advertised_groups":{"references":["var.router_advertise_config","var.router_advertise_config.mode","var.router_advertise_config","var.router_advertise_config.groups","var.router_advertise_config"]},"asn":{"references":["var.router_asn"]},"keepalive_interval":{"references":["var.keepalive_interval"]}}],"name":{"references":["var.name"]},"network":{"references":["var.network"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]}},"schema_version":0,"count_expression":{"references":["var.router_name"]}},{"address":"google_compute_router_interface.router_interface","mode":"managed","type":"google_compute_router_interface","name":"router_interface","provider_config_key":"google","expressions":{"ip_range":{"references":["each.value.bgp_session_range","each.value","each.value.bgp_session_range","each.value"]},"name":{"references":["each.value.bgp_session_name","each.value","each.value.bgp_session_name","each.value","var.name","each.key"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"router":{"references":["local.router"]},"vpn_tunnel":{"references":["google_compute_vpn_tunnel.tunnels","each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.tunnels"]}},{"address":"google_compute_router_peer.bgp_peer","mode":"managed","type":"google_compute_router_peer","name":"bgp_peer","provider_config_key":"google","expressions":{"advertise_mode":{"references":["each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.advertise_mode","each.value.bgp_peer_options","each.value"]},"advertised_groups":{"references":["each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.advertise_mode","each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.advertise_groups","each.value.bgp_peer_options","each.value"]},"advertised_route_priority":{"references":["each.value.bgp_peer_options","each.value","var.route_priority","each.value.bgp_peer_options.route_priority","each.value.bgp_peer_options","each.value","var.route_priority","each.value.bgp_peer_options.route_priority","each.value.bgp_peer_options","each.value"]},"interface":{"references":["google_compute_router_interface.router_interface","each.key"]},"ip_address":{"references":["each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.ip_address","each.value.bgp_peer_options","each.value"]},"name":{"references":["each.value.bgp_session_name","each.value","each.value.bgp_session_name","each.value","var.name","each.key"]},"peer_asn":{"references":["each.value.bgp_peer.asn","each.value.bgp_peer","each.value"]},"peer_ip_address":{"references":["each.value.bgp_peer.address","each.value.bgp_peer","each.value"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"router":{"references":["local.router"]}},"schema_version":0,"for_each_expression":{"references":["var.tunnels"]}},{"address":"google_compute_vpn_tunnel.tunnels","mode":"managed","type":"google_compute_vpn_tunnel","name":"tunnels","provider_config_key":"google","expressions":{"ike_version":{"references":["each.value.ike_version","each.value"]},"labels":{"references":["var.labels"]},"name":{"references":["var.name","each.key"]},"peer_external_gateway":{"references":["each.value.peer_external_gateway_self_link","each.value","each.value.peer_external_gateway_self_link","each.value","local.peer_external_gateway"]},"peer_external_gateway_interface":{"references":["each.value.peer_external_gateway_interface","each.value"]},"peer_gcp_gateway":{"references":["var.peer_gcp_gateway"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"router":{"references":["local.router"]},"shared_secret":{"references":["each.value.shared_secret","each.value","local.secret","each.value.shared_secret","each.value"]},"vpn_gateway":{"references":["local.vpn_gateway_self_link"]},"vpn_gateway_interface":{"references":["each.value.vpn_gateway_interface","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.tunnels"]}},{"address":"random_id.secret","mode":"managed","type":"random_id","name":"secret","provider_config_key":"random","expressions":{"byte_length":{"references":["var.ipsec_secret_length"]}},"schema_version":0}],"variables":{"create_vpn_gateway":{"default":true,"description":"create a VPN gateway"},"external_vpn_gateway_description":{"default":"Terraform managed external VPN gateway","description":"An optional description of external VPN Gateway"},"ipsec_secret_length":{"default":8,"description":"The lnegth the of shared secret for VPN tunnels"},"keepalive_interval":{"default":20,"description":"The interval in seconds between BGP keepalive messages that are sent to the peer."},"labels":{"default":{},"description":"Labels for vpn components"},"name":{"description":"VPN gateway name, and prefix used for dependent resources."},"network":{"description":"VPC used for the gateway and routes."},"peer_external_gateway":{"default":null,"description":"Configuration of an external VPN gateway to which this VPN is connected."},"peer_gcp_gateway":{"default":null,"description":"Self Link URL of the peer side HA GCP VPN gateway to which this VPN tunnel is connected."},"project_id":{"description":"Project where resources will be created."},"region":{"description":"Region used for resources."},"route_priority":{"default":1000,"description":"Route priority, defaults to 1000."},"router_advertise_config":{"default":null,"description":"Router custom advertisement configuration, ip_ranges is a map of address ranges and descriptions."},"router_asn":{"default":64514,"description":"Router ASN used for auto-created router."},"router_name":{"default":"","description":"Name of router, leave blank to create one."},"stack_type":{"default":"IPV4_ONLY","description":"The IP stack type will apply to all the tunnels associated with this VPN gateway."},"tunnels":{"default":{},"description":"VPN tunnel configurations, bgp_peer_options is usually null."},"vpn_gateway_self_link":{"default":null,"description":"self_link of existing VPN gateway to be used for the vpn tunnel. create_vpn_gateway should be set to false"}}},"version_constraint":"~\u003e 4.0"}},"variables":{"private_worker_pool":{"default":{"create_peered_network":true,"disk_size_gb":100,"enable_network_peering":true,"machine_type":"e2-medium","name":"","no_external_ip":true,"peered_network_id":"","peered_network_subnet_ip":"","peering_address":null,"peering_prefix_length":24,"region":"us-central1"},"description":" name: Name of the worker pool. A name with a random suffix is generated if not set.\n region: The private worker pool region. See https://cloud.google.com/build/docs/locations for available locations.\n disk_size_gb: Size of the disk attached to the worker, in GB.\n machine_type: Machine type of a worker.\n no_external_ip: If true, workers are created without any public address, which prevents network egress to public IPs.\n enable_network_peering: Set to true to enable configuration of networking peering for the private worker pool.\n create_peered_network: If true a network will be created to stablish the network peering.\n peered_network_id: The ID of the existing network to configure peering for the private worker pool if create_peered_network false. The project containing the network must have Service Networking API (`servicenetworking.googleapis.com`) enabled.\n peered_network_subnet_ip: The IP range to be used for the subnet that a will created in the peered network if create_peered_network true.\n peering_address: The IP address or beginning of the peering address range. This can be supplied as an input to reserve a specific address or omitted to allow GCP to choose a valid one.\n peering_prefix_length: The prefix length of the IP peering range. If not present, it means the address field is a single IP address.\n"},"project_id":{"description":"ID of the project where the private pool will be created"},"vpc_flow_logs":{"default":{"aggregation_interval":"INTERVAL_5_SEC","filter_expr":"true","flow_sampling":"0.5","metadata":"INCLUDE_ALL_METADATA","metadata_fields":[]},"description":" aggregation_interval: Toggles the aggregation interval for collecting flow logs. Increasing the interval time will reduce the amount of generated flow logs for long lasting connections. Possible values are: INTERVAL_5_SEC, INTERVAL_30_SEC, INTERVAL_1_MIN, INTERVAL_5_MIN, INTERVAL_10_MIN, INTERVAL_15_MIN.\n flow_sampling: Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported. The value of the field must be in [0, 1].\n metadata: Configures whether metadata fields should be added to the reported VPC flow logs. Possible values are: EXCLUDE_ALL_METADATA, INCLUDE_ALL_METADATA, CUSTOM_METADATA.\n metadata_fields: ist of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and \"metadata\" is set to CUSTOM_METADATA.\n filter_expr: Export filter used to define which VPC flow logs should be logged, as as CEL expression. See https://cloud.google.com/vpc/docs/flow-logs#filtering for details on how to format this field.\n"},"vpn_configuration":{"default":{"bgp_peer_asn":64513,"enable_vpn":false,"on_prem_public_ip_address0":"","on_prem_public_ip_address1":"","psk_secret_name":"","psk_secret_project_id":"","router_asn":64515,"tunnel0_bgp_peer_address":"","tunnel0_bgp_session_range":"","tunnel1_bgp_peer_address":"","tunnel1_bgp_session_range":""},"description":" enable_vpn: set to true to create VPN connection to on prem. If true, the following values must be valid.\n on_prem_public_ip_address0: The first public IP address for on prem VPN connection.\n on_prem_public_ip_address1: The second public IP address for on prem VPN connection.\n router_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for cloud routes.\n bgp_peer_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for peer cloud routes.\n shared_secret: The shared secret used in the VPN.\n psk_secret_project_id: The ID of the project that contains the secret from secret manager that holds the VPN pre-shared key.\n psk_secret_name: The name of the secret to retrieve from secret manager that holds the VPN pre-shared key.\n tunnel0_bgp_peer_address: BGP peer address for tunnel 0.\n tunnel0_bgp_session_range: BGP session range for tunnel 0.\n tunnel1_bgp_peer_address: BGP peer address for tunnel 1.\n tunnel1_bgp_session_range: BGP session range for tunnel 1.\n"}}}},"tf_source":{"source":"terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_source","expressions":{"activate_apis":{"constant_value":["serviceusage.googleapis.com","servicenetworking.googleapis.com","compute.googleapis.com","logging.googleapis.com","iam.googleapis.com","admin.googleapis.com","sourcerepo.googleapis.com","workflows.googleapis.com","artifactregistry.googleapis.com","cloudbuild.googleapis.com","cloudscheduler.googleapis.com","bigquery.googleapis.com","cloudresourcemanager.googleapis.com","cloudbilling.googleapis.com","appengine.googleapis.com","storage-api.googleapis.com","billingbudgets.googleapis.com","dns.googleapis.com"]},"billing_account":{"references":["var.billing_account"]},"buckets_force_destroy":{"references":["var.bucket_force_destroy"]},"cloud_source_repos":{"references":["local.base_cloud_source_repos","local.cloud_source_repos"]},"folder_id":{"references":["google_folder.bootstrap.id","google_folder.bootstrap"]},"group_org_admins":{"references":["var.groups.required_groups.group_org_admins","var.groups.required_groups","var.groups"]},"location":{"references":["var.default_region"]},"org_id":{"references":["var.org_id"]},"project_deletion_policy":{"references":["var.project_deletion_policy"]},"project_id":{"references":["var.project_prefix","random_string.suffix.result","random_string.suffix"]},"project_labels":{"constant_value":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"}}},"module":{"outputs":{"cloudbuild_project_id":{"expression":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"depends_on":["google_storage_bucket_iam_member.cloudbuild_iam","google_project_iam_member.org_admins_cloudbuild_editor","google_project_iam_member.org_admins_cloudbuild_viewer","google_project_iam_member.org_admins_source_repo_admin"],"description":"Project for CloudBuild and Cloud Source Repositories."},"csr_repos":{"expression":{"references":["google_sourcerepo_repository.gcp_repo"]},"description":"List of Cloud Source Repos created by the module."},"gcs_cloudbuild_default_bucket":{"expression":{"references":["module.cloudbuild_bucket.bucket.name","module.cloudbuild_bucket.bucket","module.cloudbuild_bucket"]},"depends_on":["google_storage_bucket_iam_member.cloudbuild_iam"],"description":"Bucket used to store temporary files in CloudBuild project."}},"resources":[{"address":"google_project_iam_member.org_admins_cloudbuild_editor","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_editor","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"role":{"constant_value":"roles/cloudbuild.builds.editor"}},"schema_version":0},{"address":"google_project_iam_member.org_admins_cloudbuild_viewer","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_viewer","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0},{"address":"google_project_iam_member.org_admins_source_repo_admin","mode":"managed","type":"google_project_iam_member","name":"org_admins_source_repo_admin","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"role":{"constant_value":"roles/source.admin"}},"schema_version":0,"count_expression":{"references":["var.cloud_source_repos"]}},{"address":"google_sourcerepo_repository.gcp_repo","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","provider_config_key":"google","expressions":{"name":{"references":["each.value"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]}},"schema_version":0,"for_each_expression":{"references":["var.cloud_source_repos","var.cloud_source_repos"]}},{"address":"google_storage_bucket_iam_member.cloudbuild_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"cloudbuild_iam","provider_config_key":"google","expressions":{"bucket":{"references":["module.cloudbuild_bucket.bucket.name","module.cloudbuild_bucket.bucket","module.cloudbuild_bucket"]},"member":{"references":["module.cloudbuild_project.project_number","module.cloudbuild_project"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0}],"module_calls":{"cloudbuild_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"labels":{"references":["var.storage_bucket_labels"]},"location":{"references":["var.location"]},"name":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"project_id":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"},"cloudbuild_project":{"source":"terraform-google-modules/project-factory/google","expressions":{"activate_apis":{"references":["local.activate_apis"]},"auto_create_network":{"references":["var.project_auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"deletion_policy":{"references":["var.project_deletion_policy"]},"disable_services_on_destroy":{"constant_value":false},"folder_id":{"references":["var.folder_id"]},"labels":{"references":["var.project_labels"]},"name":{"references":["local.cloudbuild_project_id"]},"org_id":{"references":["var.org_id"]},"random_project_id":{"references":["local.use_random_suffix"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["module.project-factory.api_s_account","module.project-factory"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["module.project-factory.api_s_account_fmt","module.project-factory"]},"description":"API service account email formatted for terraform use"},"budget_name":{"expression":{"references":["module.budget.name","module.budget"]},"description":"The name of the budget if created"},"domain":{"expression":{"references":["module.gsuite_group.domain","module.gsuite_group"]},"description":"The organization's domain"},"enabled_api_identities":{"expression":{"references":["module.project-factory.enabled_api_identities","module.project-factory"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project-factory.enabled_apis","module.project-factory"]},"description":"Enabled APIs in the project"},"group_email":{"expression":{"references":["module.gsuite_group.email","module.gsuite_group"]},"description":"The email of the G Suite group with group_name"},"project_bucket_self_link":{"expression":{"references":["module.project-factory.project_bucket_self_link","module.project-factory"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["module.project-factory.project_bucket_url","module.project-factory"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project-factory.project_id","module.project-factory"]},"description":"ID of the project"},"project_name":{"expression":{"references":["module.project-factory.project_name","module.project-factory"]},"description":"Name of the project"},"project_number":{"expression":{"references":["module.project-factory.project_number","module.project-factory"]},"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["module.project-factory.service_account_display_name","module.project-factory"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["module.project-factory.service_account_email","module.project-factory"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["module.project-factory.service_account_id","module.project-factory"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["module.project-factory.service_account_name","module.project-factory"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["module.project-factory.service_account_unique_id","module.project-factory"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["module.project-factory.tag_bindings","module.project-factory"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["module.project-factory.usage_report_export_bucket","module.project-factory"]},"description":"GCE usage reports bucket"}},"module_calls":{"budget":{"source":"./modules/budget","expressions":{"alert_pubsub_topic":{"references":["var.budget_alert_pubsub_topic"]},"alert_spend_basis":{"references":["var.budget_alert_spend_basis"]},"alert_spent_percents":{"references":["var.budget_alert_spent_percents"]},"amount":{"references":["var.budget_amount"]},"billing_account":{"references":["var.billing_account"]},"calendar_period":{"references":["var.budget_calendar_period"]},"create_budget":{"references":["var.budget_amount"]},"custom_period_end_date":{"references":["var.budget_custom_period_end_date"]},"custom_period_start_date":{"references":["var.budget_custom_period_start_date"]},"display_name":{"references":["var.budget_display_name","var.budget_display_name"]},"labels":{"references":["var.budget_labels"]},"monitoring_notification_channels":{"references":["var.budget_monitoring_notification_channels"]},"projects":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"name":{"expression":{"references":["google_billing_budget.budget","google_billing_budget.budget[0].name","google_billing_budget.budget[0]","google_billing_budget.budget"]},"description":"Resource name of the budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}.`"}},"resources":[{"address":"google_billing_budget.budget","mode":"managed","type":"google_billing_budget","name":"budget","provider_config_key":"google","expressions":{"amount":[{"specified_amount":[{"units":{"references":["var.amount"]}}]}],"billing_account":{"references":["var.billing_account"]},"budget_filter":[{"calendar_period":{"references":["local.custom_period","var.calendar_period"]},"credit_types_treatment":{"references":["var.credit_types_treatment"]},"labels":{"references":["var.labels"]},"projects":{"references":["local.projects"]},"services":{"references":["local.services"]}}],"display_name":{"references":["local.display_name"]}},"schema_version":1,"count_expression":{"references":["var.create_budget"]}},{"address":"data.google_project.project","mode":"data","type":"google_project","name":"project","provider_config_key":"google","expressions":{"project_id":{"references":["var.projects","count.index"]}},"schema_version":0,"count_expression":{"references":["var.create_budget","var.projects"]},"depends_on":["var.projects"]}],"variables":{"alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"amount":{"description":"The amount to use as the budget"},"billing_account":{"description":"ID of the billing account to set a budget on"},"calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"create_budget":{"default":true,"description":"If the budget should be created"},"credit_types_treatment":{"default":"INCLUDE_ALL_CREDITS","description":"Specifies how credits should be treated when determining spend for threshold calculations"},"custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"projects":{"description":"The project ids to include in this budget. If empty budget will include all projects"},"services":{"default":null,"description":"A list of services ids to be included in the budget. If omitted, all services will be included in the budget. Service ids can be found at https://cloud.google.com/skus/"}}}},"essential_contacts":{"source":"./modules/essential_contacts","expressions":{"essential_contacts":{"references":["var.essential_contacts"]},"language_tag":{"references":["var.language_tag"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"essential_contacts":{"expression":{"references":["google_essential_contacts_contact.contact"]},"description":"Essential Contact resources created"},"project_id":{"expression":{"references":["var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_essential_contacts_contact.contact","mode":"managed","type":"google_essential_contacts_contact","name":"contact","provider_config_key":"google","expressions":{"email":{"references":["each.key"]},"language_tag":{"references":["var.language_tag"]},"notification_category_subscriptions":{"references":["each.value"]},"parent":{"references":["var.project_id"]}},"schema_version":0,"for_each_expression":{"references":["var.essential_contacts"]}}],"variables":{"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"language_tag":{"description":"Language code to be used for essential contacts notifiactions"},"project_id":{"description":"The GCP project you want to send Essential Contacts notifications for"}}}},"gsuite_group":{"source":"./modules/gsuite_group","expressions":{"domain":{"references":["var.domain"]},"name":{"references":["var.group_name"]},"org_id":{"references":["var.org_id"]}},"module":{"outputs":{"domain":{"expression":{"references":["local.domain"]},"description":"The domain of the group's organization."},"email":{"expression":{"references":["local.email"]},"description":"The email address of the group."},"name":{"expression":{"references":["var.name"]},"description":"The username portion of the email address of the group."}},"resources":[{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"organization":{"references":["var.org_id"]}},"schema_version":0,"count_expression":{"references":["var.domain","var.name"]}}],"variables":{"domain":{"default":"","description":"The domain name"},"name":{"default":"","description":"The name of the group."},"org_id":{"default":null,"description":"The organization ID."}}}},"project-factory":{"source":"./modules/core_project_factory","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["var.activate_apis"]},"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"bucket_force_destroy":{"references":["var.bucket_force_destroy"]},"bucket_labels":{"references":["var.bucket_labels"]},"bucket_location":{"references":["var.bucket_location"]},"bucket_name":{"references":["var.bucket_name"]},"bucket_pap":{"references":["var.bucket_pap"]},"bucket_project":{"references":["var.bucket_project"]},"bucket_ula":{"references":["var.bucket_ula"]},"bucket_versioning":{"references":["var.bucket_versioning"]},"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"create_project_sa":{"references":["var.create_project_sa"]},"default_network_tier":{"references":["var.default_network_tier"]},"default_service_account":{"references":["var.default_service_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"enable_shared_vpc_host_project":{"references":["var.enable_shared_vpc_host_project"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"folder_id":{"references":["var.folder_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"group_email":{"references":["module.gsuite_group.email","module.gsuite_group"]},"group_role":{"references":["var.group_role"]},"labels":{"references":["var.labels"]},"lien":{"references":["var.lien"]},"manage_group":{"references":["var.group_name"]},"name":{"references":["var.name"]},"org_id":{"references":["var.folder_id","var.org_id"]},"project_id":{"references":["var.project_id"]},"project_sa_name":{"references":["var.project_sa_name"]},"random_project_id":{"references":["var.random_project_id"]},"random_project_id_length":{"references":["var.random_project_id_length"]},"sa_role":{"references":["var.sa_role"]},"shared_vpc":{"references":["var.svpc_host_project_id"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]},"tag_binding_values":{"references":["var.tag_binding_values"]},"usage_bucket_name":{"references":["var.usage_bucket_name"]},"usage_bucket_prefix":{"references":["var.usage_bucket_prefix"]},"vpc_service_control_attach_dry_run":{"references":["var.vpc_service_control_attach_dry_run"]},"vpc_service_control_attach_enabled":{"references":["var.vpc_service_control_attach_enabled"]},"vpc_service_control_perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"vpc_service_control_sleep_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["local.api_s_account"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["local.api_s_account_fmt"]},"description":"API service account email formatted for terraform use"},"enabled_api_identities":{"expression":{"references":["module.project_services.enabled_api_identities","module.project_services"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project_services.enabled_apis","module.project_services"]},"description":"Enabled APIs in the project"},"project_bucket_name":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"The name of the projec's bucket"},"project_bucket_self_link":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project_services.project_id","module.project_services"]},"depends_on":["module.project_services","google_project.main","google_compute_shared_vpc_service_project.shared_vpc_attachment","google_compute_shared_vpc_host_project.shared_vpc_host"],"description":"ID of the project"},"project_name":{"expression":{"references":["google_project.main.name","google_project.main"]},"description":"Name of the project"},"project_number":{"expression":{"references":["google_project.main.number","google_project.main"]},"depends_on":["module.project_services"],"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].display_name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].account_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].unique_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["google_tags_tag_binding.bindings"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["google_project_usage_export_bucket.usage_report_export[0]","google_project_usage_export_bucket.usage_report_export"]},"description":"GCE usage reports bucket"}},"resources":[{"address":"google_access_context_manager_service_perimeter_dry_run_resource.service_perimeter_attachment_dry_run","mode":"managed","type":"google_access_context_manager_service_perimeter_dry_run_resource","name":"service_perimeter_attachment_dry_run","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_dry_run","var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_access_context_manager_service_perimeter_resource.service_perimeter_attachment","mode":"managed","type":"google_access_context_manager_service_perimeter_resource","name":"service_perimeter_attachment","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_compute_project_cloud_armor_tier.cloud_armor_tier_config","mode":"managed","type":"google_compute_project_cloud_armor_tier","name":"cloud_armor_tier_config","provider_config_key":"google","expressions":{"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.cloud_armor_tier"]}},{"address":"google_compute_project_default_network_tier.default","mode":"managed","type":"google_compute_project_default_network_tier","name":"default","provider_config_key":"google","expressions":{"network_tier":{"references":["var.default_network_tier"]},"project":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.default_network_tier"]}},{"address":"google_compute_shared_vpc_host_project.shared_vpc_host","mode":"managed","type":"google_compute_shared_vpc_host_project","name":"shared_vpc_host","provider_config_key":"google-beta","expressions":{"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_host_project"]},"depends_on":["module.project_services"]},{"address":"google_compute_shared_vpc_service_project.shared_vpc_attachment","mode":"managed","type":"google_compute_shared_vpc_service_project","name":"shared_vpc_attachment","provider_config_key":"google-beta","expressions":{"host_project":{"references":["var.shared_vpc"]},"service_project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_service_project"]},"depends_on":["time_sleep.wait_5_seconds[0]","module.project_services"]},{"address":"google_compute_subnetwork_iam_member.apis_service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"apis_service_account_role_to_vpc_subnets","provider_config_key":"google-beta","expressions":{"member":{"references":["local.api_s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.shared_vpc_subnets"]},"depends_on":["module.project_services"]},{"address":"google_compute_subnetwork_iam_member.group_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"group_role_to_vpc_subnets","provider_config_key":"google-beta","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.manage_group","var.shared_vpc_subnets"]}},{"address":"google_compute_subnetwork_iam_member.service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_account_role_to_vpc_subnets","provider_config_key":"google-beta","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.create_project_sa","var.shared_vpc_subnets"]}},{"address":"google_project.main","mode":"managed","type":"google_project","name":"main","provider_config_key":"google","expressions":{"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"folder_id":{"references":["local.project_folder_id"]},"labels":{"references":["var.labels"]},"name":{"references":["var.name"]},"org_id":{"references":["local.project_org_id"]},"project_id":{"references":["local.temp_project_id"]}},"schema_version":1},{"address":"google_project_default_service_accounts.default_service_accounts","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","provider_config_key":"google","expressions":{"action":{"references":["var.default_service_account"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"restore_policy":{"constant_value":"REVERT_AND_IGNORE_FAILURE"}},"schema_version":0,"count_expression":{"references":["var.default_service_account"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.controlling_group_vpc_membership","mode":"managed","type":"google_project_iam_member","name":"controlling_group_vpc_membership","provider_config_key":"google","expressions":{"member":{"references":["local.shared_vpc_users","count.index"]},"project":{"references":["var.shared_vpc"]},"role":{"constant_value":"roles/compute.networkUser"}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","local.shared_vpc_users_length"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.default_service_account_membership","mode":"managed","type":"google_project_iam_member","name":"default_service_account_membership","provider_config_key":"google","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.sa_role"]}},"schema_version":0,"count_expression":{"references":["var.sa_role","var.create_project_sa"]}},{"address":"google_project_iam_member.gsuite_group_role","mode":"managed","type":"google_project_iam_member","name":"gsuite_group_role","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.group_role"]}},"schema_version":0,"count_expression":{"references":["var.manage_group"]}},{"address":"google_project_service.enable_access_context_manager","mode":"managed","type":"google_project_service","name":"enable_access_context_manager","provider_config_key":"google","expressions":{"project":{"references":["google_project.main.number","google_project.main"]},"service":{"constant_value":"accesscontextmanager.googleapis.com"}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]}},{"address":"google_project_usage_export_bucket.usage_report_export","mode":"managed","type":"google_project_usage_export_bucket","name":"usage_report_export","provider_config_key":"google","expressions":{"bucket_name":{"references":["var.usage_bucket_name"]},"prefix":{"references":["var.usage_bucket_prefix","var.usage_bucket_prefix","google_project.main.project_id","google_project.main"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.usage_bucket_name"]},"depends_on":["module.project_services"]},{"address":"google_resource_manager_lien.lien","mode":"managed","type":"google_resource_manager_lien","name":"lien","provider_config_key":"google","expressions":{"origin":{"constant_value":"project-factory"},"parent":{"references":["google_project.main.number","google_project.main"]},"reason":{"constant_value":"Project Factory lien"},"restrictions":{"constant_value":["resourcemanager.projects.delete"]}},"schema_version":0,"count_expression":{"references":["var.lien"]}},{"address":"google_service_account.default_service_account","mode":"managed","type":"google_service_account","name":"default_service_account","provider_config_key":"google","expressions":{"account_id":{"references":["var.project_sa_name"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["var.name"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.create_project_sa"]}},{"address":"google_service_account_iam_member.service_account_grant_to_group","mode":"managed","type":"google_service_account_iam_member","name":"service_account_grant_to_group","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["google_project.main.project_id","google_project.main","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]}},"schema_version":0,"count_expression":{"references":["var.manage_group","var.create_project_sa"]}},{"address":"google_storage_bucket.project_bucket","mode":"managed","type":"google_storage_bucket","name":"project_bucket","provider_config_key":"google-beta","expressions":{"force_destroy":{"references":["var.bucket_force_destroy"]},"labels":{"references":["var.bucket_labels"]},"location":{"references":["var.bucket_location"]},"name":{"references":["local.project_bucket_name"]},"project":{"references":["var.bucket_project","local.base_project_id","google_project.main.project_id","google_project.main","var.bucket_project"]},"public_access_prevention":{"references":["var.bucket_pap"]},"uniform_bucket_level_access":{"references":["var.bucket_ula"]},"versioning":[{"enabled":{"references":["var.bucket_versioning"]}}]},"schema_version":3,"count_expression":{"references":["local.create_bucket"]}},{"address":"google_storage_bucket_iam_member.api_s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"api_s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.api_s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket"]},"depends_on":["module.project_services"]},{"address":"google_storage_bucket_iam_member.group_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"group_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.manage_group"]}},{"address":"google_storage_bucket_iam_member.s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.create_project_sa"]}},{"address":"google_tags_tag_binding.bindings","mode":"managed","type":"google_tags_tag_binding","name":"bindings","provider_config_key":"google","expressions":{"parent":{"references":["google_project.main.number","google_project.main"]},"tag_value":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.tag_binding_values"]}},{"address":"random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_config_key":"module.tf_source.module.cloudbuild_project.module.project-factory:random","expressions":{"byte_length":{"constant_value":2}},"schema_version":0},{"address":"random_string.random_project_id_suffix","mode":"managed","type":"random_string","name":"random_project_id_suffix","provider_config_key":"module.tf_source.module.cloudbuild_project.module.project-factory:random","expressions":{"length":{"references":["var.random_project_id_length"]},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2,"count_expression":{"references":["local.use_random_string"]}},{"address":"time_sleep.wait_5_seconds","mode":"managed","type":"time_sleep","name":"wait_5_seconds","provider_config_key":"module.tf_source.module.cloudbuild_project.module.project-factory:time","expressions":{"create_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]},"depends_on":["google_access_context_manager_service_perimeter_resource.service_perimeter_attachment[0]","google_project_service.enable_access_context_manager[0]"]}],"module_calls":{"project_services":{"source":"../project_services","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["local.activate_apis"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"project_id":{"references":["google_project.main.project_id","google_project.main"]}},"module":{"outputs":{"enabled_api_identities":{"expression":{"references":["google_project_service_identity.project_service_identities"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["google_project_service.project_services"]},"description":"Enabled APIs in the project"},"project_id":{"expression":{"references":["google_project_service.project_services","var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_project_iam_member.project_service_identity_roles","mode":"managed","type":"google_project_iam_member","name":"project_service_identity_roles","provider_config_key":"google","expressions":{"member":{"references":["each.value.email","each.value"]},"project":{"references":["var.project_id"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.add_service_roles"]}},{"address":"google_project_service.project_services","mode":"managed","type":"google_project_service","name":"project_services","provider_config_key":"google","expressions":{"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_on_destroy":{"references":["var.disable_services_on_destroy"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.services"]}},{"address":"google_project_service_identity.project_service_identities","mode":"managed","type":"google_project_service_identity","name":"project_service_identities","provider_config_key":"google-beta","expressions":{"project":{"references":["var.project_id"]},"service":{"references":["each.value.api","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.activate_api_identities"]}},{"address":"data.google_compute_default_service_account.default","mode":"data","type":"google_compute_default_service_account","name":"default","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.activate_compute_identity"]}}],"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":[],"description":"The list of apis to activate within the project"},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_dependent_services"},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_on_destroy"},"enable_apis":{"default":true,"description":"Whether to actually enable the APIs. If false, this module is a no-op."},"project_id":{"description":"The GCP project you want to enable APIs on"}}}}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`. Use for services supported by `gcloud beta services identity create`\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false."},"enable_shared_vpc_service_project":{"description":"If this project should be attached to a shared VPC. If true, you must set shared_vpc variable."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"group_email":{"default":"","description":"The email address of a group to control the project by being assigned group_role."},"group_role":{"default":"","description":"The role to give the controlling group (group_name) over the project."},"labels":{"default":{},"description":"Map of labels for project"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"manage_group":{"default":false,"description":"A toggle to indicate if a G Suite group should be managed."},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}}},"quotas":{"source":"./modules/quota_manager","expressions":{"consumer_quotas":{"references":["var.consumer_quotas"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"quota_overrides":{"expression":{"references":["google_service_usage_consumer_quota_override.override"]},"description":"The server-generated names of the quota override."}},"resources":[{"address":"google_service_usage_consumer_quota_override.override","mode":"managed","type":"google_service_usage_consumer_quota_override","name":"override","provider_config_key":"google-beta","expressions":{"dimensions":{"references":["each.value.dimensions","each.value"]},"force":{"constant_value":true},"limit":{"references":["each.value.limit","each.value"]},"metric":{"references":["each.value.metric","each.value"]},"override_value":{"references":["each.value.value","each.value"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value.service","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.consumer_quotas"]}}],"variables":{"consumer_quotas":{"description":"The quotas configuration you want to override for the project."},"project_id":{"description":"The GCP project where you want to manage the consumer quotas"}}}},"shared_vpc_access":{"source":"./modules/shared_vpc_access","expressions":{"active_apis":{"references":["var.activate_apis","var.activate_api_identities"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"grant_services_security_admin_role":{"references":["var.grant_services_security_admin_role"]},"host_project_id":{"references":["var.svpc_host_project_id"]},"lookup_project_numbers":{"constant_value":false},"service_project_id":{"references":["module.project-factory.project_id","module.project-factory"]},"service_project_number":{"references":["module.project-factory.project_number","module.project-factory"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]}},"module":{"outputs":{"active_api_service_accounts":{"expression":{"references":["local.active_apis"]},"description":"List of active API service accounts in the service project."},"project_id":{"expression":{"references":["var.service_project_id"]},"depends_on":["google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","google_project_iam_member.gke_host_agent","google_project_iam_member.service_shared_vpc_user"],"description":"Service project ID."}},"resources":[{"address":"google_compute_subnetwork_iam_member.cloudservices_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"cloudservices_shared_vpc_subnet_users","provider_config_key":"google-beta","expressions":{"member":{"references":["local.service_project_number"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role","local.subnetwork_api"]}},{"address":"google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_shared_vpc_subnet_users","provider_config_key":"google-beta","expressions":{"member":{"references":["local.apis","local.subnetwork_api","count.index"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"references":["local.apis","local.subnetwork_api","count.index"]},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","local.subnetwork_api"]}},{"address":"google_project_iam_member.composer_host_agent","mode":"managed","type":"google_project_iam_member","name":"composer_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"composer.googleapis.com\"].service_account","local.apis[\"composer.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/composer.sharedVpcAgent"}},"schema_version":0,"count_expression":{"references":["local.composer_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datasfusion_network_viewer","mode":"managed","type":"google_project_iam_member","name":"datasfusion_network_viewer","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datafusion.googleapis.com\"].service_account","local.apis[\"datafusion.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkViewer"}},"schema_version":0,"count_expression":{"references":["local.datafusion_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datastream_network_admin","mode":"managed","type":"google_project_iam_member","name":"datastream_network_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datastream.googleapis.com\"].service_account","local.apis[\"datastream.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkAdmin"}},"schema_version":0,"count_expression":{"references":["local.datastream_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_network_admin_role"]}},{"address":"google_project_iam_member.gke_host_agent","mode":"managed","type":"google_project_iam_member","name":"gke_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/container.hostServiceAgentUser"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.gke_security_admin","mode":"managed","type":"google_project_iam_member","name":"gke_security_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.securityAdmin"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_security_admin_role"]}},{"address":"google_project_iam_member.service_shared_vpc_user","mode":"managed","type":"google_project_iam_member","name":"service_shared_vpc_user","provider_config_key":"google","expressions":{"member":{"references":["local.apis","each.value"]},"project":{"references":["var.host_project_id"]},"role":{"references":["local.apis","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.shared_vpc_subnets","var.enable_shared_vpc_service_project","var.grant_network_role","local.active_apis"]}},{"address":"data.google_project.service_project","mode":"data","type":"google_project","name":"service_project","provider_config_key":"google","expressions":{"project_id":{"references":["var.service_project_id"]}},"schema_version":0,"count_expression":{"references":["var.lookup_project_numbers"]}}],"variables":{"active_apis":{"default":[],"description":"The list of active apis on the service project. If api is not active this module will not try to activate it"},"enable_shared_vpc_service_project":{"description":"Flag set if SVPC enabled"},"grant_network_role":{"default":true,"description":"Whether or not to grant service agents the network roles on the host project"},"grant_services_network_admin_role":{"default":false,"description":"Whether or not to grant Datastream Service acount the Network Admin role on the host project so it can manage firewall rules"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"host_project_id":{"description":"The ID of the host project which hosts the shared VPC"},"lookup_project_numbers":{"default":true,"description":"Whether to look up the project numbers from data sources. If false, `service_project_number` will be used instead."},"service_project_id":{"description":"The ID of the service project"},"service_project_number":{"default":null,"description":"Project number of the service project. Will be used if `lookup_service_project_number` is false."},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"}}},"depends_on":["module.project-factory.enabled_apis"]}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"budget_alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"budget_alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"budget_alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"budget_amount":{"default":null,"description":"The amount to use for a budget alert"},"budget_calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"budget_custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"budget_labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"budget_monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"consumer_quotas":{"default":[],"description":"The quotas configuration you want to override for the project."},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"domain":{"default":"","description":"The domain name (optional)."},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set svpc_host_project_id variable. Default is false."},"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"group_name":{"default":"","description":"A group to control the project by being assigned group_role (defaults to project editor)"},"group_role":{"default":"roles/editor","description":"The role to give the controlling group (group_name) over the project (defaults to project editor)"},"labels":{"default":{},"description":"Map of labels for project"},"language_tag":{"default":"en-US","description":"Language code to be used for essential contacts notifications"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"svpc_host_project_id":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}},"version_constraint":"~\u003e 18.0"}},"variables":{"activate_apis":{"default":["serviceusage.googleapis.com","servicenetworking.googleapis.com","compute.googleapis.com","logging.googleapis.com","iam.googleapis.com","admin.googleapis.com"],"description":"List of APIs to enable in the Cloudbuild project."},"billing_account":{"description":"The ID of the billing account to associate projects with."},"buckets_force_destroy":{"default":false,"description":"When deleting CloudBuild buckets, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"cloud_source_repos":{"default":["gcp-policies","gcp-org","gcp-envs","gcp-networks","gcp-projects"],"description":"List of Cloud Source Repos to create with CloudBuild triggers."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"group_org_admins":{"description":"Google Group for GCP Organization Administrators"},"location":{"default":"us-central1","description":"Location for build artifacts bucket"},"org_id":{"description":"GCP Organization ID"},"project_auto_create_network":{"default":false,"description":"Create the default network for the project created."},"project_deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project created."},"project_id":{"default":"","description":"Custom project ID to use for project created."},"project_labels":{"default":{},"description":"Labels to apply to the project."},"storage_bucket_labels":{"default":{},"description":"Labels to apply to the storage bucket."}}},"version_constraint":"~\u003e 11.0","depends_on":["module.seed_bootstrap"]},"tf_workspace":{"source":"terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace","expressions":{"artifacts_bucket_name":{"references":["var.bucket_prefix","module.tf_source.cloudbuild_project_id","module.tf_source","local.cb_config","each.key"]},"buckets_force_destroy":{"references":["var.bucket_force_destroy"]},"cloudbuild_apply_filename":{"constant_value":"cloudbuild-tf-apply.yaml"},"cloudbuild_plan_filename":{"constant_value":"cloudbuild-tf-plan.yaml"},"cloudbuild_sa":{"references":["google_service_account.terraform-env-sa","each.key"]},"create_cloudbuild_sa":{"constant_value":false},"create_state_bucket":{"constant_value":false},"diff_sa_project":{"constant_value":true},"enable_worker_pool":{"constant_value":true},"location":{"references":["var.default_region"]},"log_bucket_name":{"references":["var.bucket_prefix","module.tf_source.cloudbuild_project_id","module.tf_source","local.cb_config","each.key"]},"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"state_bucket_self_link":{"references":["local.cb_config","each.key"]},"substitutions":{"references":["var.org_id","var.billing_account","var.default_region","module.tf_source.cloudbuild_project_id","module.tf_source","local.gar_repository","local.docker_tag_version_terraform"]},"tf_apply_branches":{"constant_value":["development","nonproduction","production"]},"tf_repo_uri":{"references":["module.tf_source.csr_repos","module.tf_source","local.cb_config","each.key"]},"trigger_location":{"references":["var.default_region"]},"worker_pool_id":{"references":["module.tf_private_pool.private_worker_pool_id","module.tf_private_pool"]}},"for_each_expression":{"references":["local.granular_sa"]},"module":{"outputs":{"artifacts_bucket":{"expression":{"references":["module.artifacts_bucket.bucket.self_link","module.artifacts_bucket.bucket","module.artifacts_bucket"]},"description":"Bucket for storing TF plans"},"cloudbuild_apply_trigger_id":{"expression":{"references":["google_cloudbuild_trigger.triggers[\"apply\"].id","google_cloudbuild_trigger.triggers[\"apply\"]","google_cloudbuild_trigger.triggers"]},"description":"Trigger used for running TF apply"},"cloudbuild_plan_trigger_id":{"expression":{"references":["google_cloudbuild_trigger.triggers[\"plan\"].id","google_cloudbuild_trigger.triggers[\"plan\"]","google_cloudbuild_trigger.triggers"]},"description":"Trigger used for running TF plan"},"cloudbuild_sa":{"expression":{"references":["local.cloudbuild_sa"]},"description":"SA used by Cloud Build triggers"},"logs_bucket":{"expression":{"references":["module.log_bucket.bucket.self_link","module.log_bucket.bucket","module.log_bucket"]},"description":"Bucket for storing TF logs"},"state_bucket":{"expression":{"references":["local.state_bucket_self_link"]},"description":"Bucket for storing TF state"}},"resources":[{"address":"google_cloudbuild_trigger.triggers","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","provider_config_key":"google","expressions":{"description":{"references":["each.key","local.repo_uri_description","var.tf_repo_dir"]},"filename":{"references":["local.default_triggers_explicit","each.key"]},"ignored_files":{"references":["var.cloudbuild_ignored_files"]},"included_files":{"references":["var.cloudbuild_included_files"]},"location":{"references":["var.trigger_location"]},"name":{"references":["local.default_prefix","each.key"]},"project":{"references":["var.project_id"]},"service_account":{"references":["local.cloudbuild_sa"]},"substitutions":{"references":["local.default_subst","var.substitutions"]}},"schema_version":2,"for_each_expression":{"references":["local.default_triggers_steps"]},"depends_on":["google_project_iam_member.cb_sa_roles"]},{"address":"google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/logging.logWriter"}},"schema_version":0},{"address":"google_project_iam_member.cb_sa_roles","mode":"managed","type":"google_project_iam_member","name":"cb_sa_roles","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["each.value.project_id","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.cb_sa_roles_expand"]}},{"address":"google_project_iam_member.pool_user","mode":"managed","type":"google_project_iam_member","name":"pool_user","provider_config_key":"google","expressions":{"member":{"references":["data.google_project.cloudbuild_project[0].number","data.google_project.cloudbuild_project[0]","data.google_project.cloudbuild_project"]},"project":{"references":["local.worker_pool_project"]},"role":{"constant_value":"roles/cloudbuild.workerPoolUser"}},"schema_version":0,"count_expression":{"references":["var.enable_worker_pool"]}},{"address":"google_service_account.cb_sa","mode":"managed","type":"google_service_account","name":"cb_sa","provider_config_key":"google","expressions":{"account_id":{"references":["var.create_cloudbuild_sa_name","var.create_cloudbuild_sa_name","local.default_prefix"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["local.default_prefix"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.create_cloudbuild_sa"]}},{"address":"google_service_account_iam_member.cb_sa_self","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"role":{"references":["each.value"]},"service_account_id":{"references":["local.cloudbuild_sa"]}},"schema_version":0,"for_each_expression":{"references":["var.diff_sa_project"]}},{"address":"google_service_account_iam_member.cb_service_agent_impersonate","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","provider_config_key":"google","expressions":{"member":{"references":["data.google_project.cloudbuild_project[0].number","data.google_project.cloudbuild_project[0]","data.google_project.cloudbuild_project"]},"role":{"constant_value":"roles/iam.serviceAccountTokenCreator"},"service_account_id":{"references":["local.cloudbuild_sa"]}},"schema_version":0,"count_expression":{"references":["var.diff_sa_project"]}},{"address":"google_sourcerepo_repository_iam_member.member","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["local.source_repo_project"]},"repository":{"references":["local.source_repo_name"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0,"count_expression":{"references":["local.is_source_repo"]}},{"address":"google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_config_key":"google","expressions":{"bucket":{"references":["module.artifacts_bucket.bucket.self_link","module.artifacts_bucket.bucket","module.artifacts_bucket"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_config_key":"google","expressions":{"bucket":{"references":["module.log_bucket.bucket.self_link","module.log_bucket.bucket","module.log_bucket"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_config_key":"google","expressions":{"bucket":{"references":["local.state_bucket_self_link"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_config_key":"google","expressions":{"project_id":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.diff_sa_project"]}}],"module_calls":{"artifacts_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"location":{"references":["var.location"]},"name":{"references":["var.artifacts_bucket_name","var.artifacts_bucket_name","local.default_prefix","var.project_id"]},"project_id":{"references":["var.project_id"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"},"log_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"location":{"references":["var.location"]},"name":{"references":["var.log_bucket_name","var.log_bucket_name","local.default_prefix","var.project_id"]},"project_id":{"references":["var.project_id"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"},"state_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"location":{"references":["var.location"]},"name":{"references":["var.create_state_bucket_name","var.create_state_bucket_name","local.default_prefix","var.project_id"]},"project_id":{"references":["var.project_id"]}},"count_expression":{"references":["var.create_state_bucket"]},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"}},"variables":{"artifacts_bucket_name":{"default":"","description":"Custom bucket name for Cloud Build artifacts."},"buckets_force_destroy":{"default":false,"description":"When deleting the bucket for storing CloudBuild logs/TF state, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"cloudbuild_apply_filename":{"default":null,"description":"Optional Cloud Build YAML definition used for terraform apply. Defaults to using inline definition."},"cloudbuild_env_vars":{"default":[],"description":"Optional list of environment variables to be used in builds. List of strings of form KEY=VALUE expected."},"cloudbuild_ignored_files":{"default":[],"description":"Optional list. Changes only affecting ignored files will not invoke a build."},"cloudbuild_included_files":{"default":[],"description":"Optional list. Changes affecting at least one of these files will invoke a build."},"cloudbuild_plan_filename":{"default":null,"description":"Optional Cloud Build YAML definition used for terraform plan. Defaults to using inline definition."},"cloudbuild_sa":{"default":"","description":"Custom SA id of form projects/{{project}}/serviceAccounts/{{email}} to be used by the CloudBuild trigger. Defaults to being created if empty."},"cloudbuild_sa_roles":{"default":{},"description":"Optional to assign to custom CloudBuild SA. Map of project name or any static key to object with project_id and list of roles."},"create_cloudbuild_sa":{"default":true,"description":"Create a Service Account for use in Cloud Build. If false `cloudbuild_sa` has to be specified."},"create_cloudbuild_sa_name":{"default":"","description":"Custom name to be used in the creation of the Cloud Build service account if `create_cloudbuild_sa` is true. Defaults to generated name if empty"},"create_state_bucket":{"default":true,"description":"Create a GCS bucket for storing state. If false `state_bucket_self_link` has to be specified."},"create_state_bucket_name":{"default":"","description":"Custom bucket name for storing TF state. Used if `create_state_bucket` is true. Defaults to generated name if empty."},"diff_sa_project":{"default":false,"description":"Set to true if `cloudbuild_sa` is in a different project for setting up https://cloud.google.com/build/docs/securing-builds/configure-user-specified-service-accounts#cross-project_set_up."},"enable_worker_pool":{"default":false,"description":"Set to true to use a private worker pool in the Cloud Build Trigger."},"location":{"default":"us-central1","description":"Location for build logs/state bucket"},"log_bucket_name":{"default":"","description":"Custom bucket name for Cloud Build logs."},"prefix":{"default":"","description":"Prefix of the state/log buckets and triggers planning/applying config. If unset computes a prefix from tf_repo_uri and tf_repo_dir variables."},"project_id":{"description":"GCP project for Cloud Build triggers, state and log buckets."},"state_bucket_self_link":{"default":"","description":"Custom GCS bucket for storing TF state. Defaults to being created if empty."},"substitutions":{"default":{},"description":"Map of substitutions to use in builds."},"tf_apply_branches":{"default":["main"],"description":"List of git branches configured to run terraform apply Cloud Build trigger. All other branches will run plan by default."},"tf_cloudbuilder":{"default":"hashicorp/terraform:1.3.10","description":"Name of the Cloud Builder image used for running build steps."},"tf_repo_dir":{"default":"","description":"The directory inside the repo where the Terrafrom root config is located. If empty defaults to repo root."},"tf_repo_type":{"default":"CLOUD_SOURCE_REPOSITORIES","description":"Type of repo. When the repo type is CLOUDBUILD_V2_REPOSITORY, it will use the generic Cloudbuild 2nd gen Repository API."},"tf_repo_uri":{"default":"","description":"The URI of the repo where Terraform configs are stored. If using Cloud Build Repositories (2nd Gen) this is the repository ID where the Dockerfile is stored. Repository ID Format is 'projects/{{project}}/locations/{{location}}/connections/{{parent_connection}}/repositories/{{name}}'."},"trigger_location":{"description":"Location of for Cloud Build triggers created in the workspace. If using private pools should be the same location as the pool."},"worker_pool_id":{"default":"","description":"Custom private worker pool ID. Format: 'projects/PROJECT_ID/locations/REGION/workerPools/PRIVATE_POOL_ID'."}}},"version_constraint":"~\u003e 11.0","depends_on":["module.tf_source","module.tf_cloud_builder"]}},"variables":{"attribute_condition":{"default":null,"description":"Workload Identity Pool Provider attribute condition expression. [More info](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider#attribute_condition)"},"billing_account":{"description":"The ID of the billing account to associate projects with."},"bucket_force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"bucket_prefix":{"default":"bkt","description":"Name prefix to use for state bucket created."},"bucket_tfstate_kms_force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete the KMS keys used for the Terraform state bucket."},"default_region":{"default":"us-central1","description":"Default region to create resources where applicable."},"default_region_2":{"default":"us-west1","description":"Secondary default region to create resources where applicable."},"default_region_gcs":{"default":"US","description":"Case-Sensitive default region to create gcs resources where applicable."},"default_region_kms":{"default":"us","description":"Secondary default region to create kms resources where applicable."},"folder_deletion_protection":{"default":"true","description":"Prevent Terraform from destroying or recreating the folder."},"folder_prefix":{"default":"fldr","description":"Name prefix to use for folders created. Should be the same in all steps."},"groups":{"description":"Contain the details of the Groups to be created."},"initial_group_config":{"default":"WITH_INITIAL_OWNER","description":"Define the group configuration when it is initialized. Valid values are: WITH_INITIAL_OWNER, EMPTY and INITIAL_GROUP_CONFIG_UNSPECIFIED."},"org_id":{"description":"GCP Organization ID"},"org_policy_admin_role":{"default":false,"description":"Additional Org Policy Admin role for admin group. You can use this for testing purposes."},"parent_folder":{"default":"","description":"Optional - for an organization with existing projects or for development/validation. It will place all the example foundation resources under the provided folder instead of the root organization. The value is the numeric folder ID. The folder must already exist."},"project_deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project created."},"project_prefix":{"default":"prj","description":"Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters."},"workflow_deletion_protection":{"default":true,"description":"Whether Terraform will be prevented from destroying a workflow. When the field is set to true or unset in Terraform state, a `terraform apply` or `terraform destroy` that would delete the workflow will fail. When the field is set to false, deleting the workflow is allowed."}}}},"relevant_attributes":[{"resource":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.random_id.random_project_id_suffix","attribute":["hex"]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace.module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service_identity.project_service_identities","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_cloud_builder.google_service_account.workflow_sa[0]","attribute":["email"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","attribute":["number"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","attribute":["number"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.gsuite_group.data.google_organization.org","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["email"]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace.module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.gcp_projects_state_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","attribute":["project_id"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["name"]},{"resource":"module.tf_source.module.cloudbuild_project.module.budget.google_billing_budget.budget","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["unique_id"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.shared_vpc_access.data.google_project.service_project[0]","attribute":["number"]},{"resource":"random_string.suffix","attribute":["result"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.random_string.random_project_id_suffix[0]","attribute":["result"]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"google_folder.bootstrap","attribute":["name"]},{"resource":"module.seed_bootstrap.google_service_account.org_terraform[0]","attribute":["email"]},{"resource":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.seed_bootstrap.google_folder_iam_member.tmp_project_creator[0]","attribute":["etag"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["name"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","attribute":["trigger_id"]},{"resource":"module.bootstrap_csr_repo.null_resource.run_destroy_command","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace.module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["email"]},{"resource":"module.seed_bootstrap.module.seed_project.module.quotas.google_service_usage_consumer_quota_override.override","attribute":[]},{"resource":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_cloud_builder.google_workflows_workflow.builder","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.build_terraform_image.null_resource.gcloud_auth_google_credentials","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["display_name"]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace.module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.gsuite_group.data.google_organization.org","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.random_id.random_project_id_suffix","attribute":["hex"]},{"resource":"module.build_terraform_image.null_resource.run_command","attribute":[]},{"resource":"google_folder.bootstrap","attribute":["id"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service_identity.project_service_identities","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.google_compute_instance.vm-proxy","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.bootstrap_csr_repo.data.external.env_override[0]","attribute":["result","download"]},{"resource":"module.tf_cloud_builder.google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.budget.data.google_project.project","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_shared_vpc_host_project.shared_vpc_host[0]","attribute":["project"]},{"resource":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.bootstrap_csr_repo.null_resource.gcloud_auth_google_credentials","attribute":[]},{"resource":"module.bootstrap_csr_repo.null_resource.run_command","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.random_string.random_project_id_suffix[0]","attribute":["result"]},{"resource":"module.bootstrap_csr_repo.null_resource.additional_components","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["name"]},{"resource":"google_service_account.terraform-env-sa[\"proj\"]","attribute":["email"]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace.module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.google_compute_router.cb-router","attribute":["region"]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","attribute":["name"]},{"resource":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.quotas.google_service_usage_consumer_quota_override.override","attribute":[]},{"resource":"data.google_project.cloudbuild_project","attribute":["number"]},{"resource":"module.tf_workspace.module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_tags_tag_binding.bindings","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace.module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace.google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.seed_bootstrap.google_storage_bucket.org_terraform_state","attribute":["name"]},{"resource":"module.tf_private_pool.google_compute_router.cb-router","attribute":["name"]},{"resource":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["unique_id"]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace.module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.budget.google_billing_budget.budget[0]","attribute":["name"]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","attribute":[]},{"resource":"module.required_group.google_cloud_identity_group.group","attribute":["name"]},{"resource":"module.seed_bootstrap.random_id.suffix","attribute":["hex"]},{"resource":"google_service_account.terraform-env-sa[\"org\"]","attribute":["email"]},{"resource":"module.tf_source.module.cloudbuild_project.module.budget.google_billing_budget.budget[0]","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.required_group.google_cloud_identity_group.group","attribute":["group_key",0,"id"]},{"resource":"module.gcp_projects_state_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["name"]},{"resource":"google_service_account.terraform-env-sa[\"net\"]","attribute":["email"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.subnets.google_compute_subnetwork.subnetwork","attribute":[]},{"resource":"module.bootstrap_csr_repo.random_id.cache[0]","attribute":["hex"]},{"resource":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"net\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.seed_bootstrap.google_organization_iam_member.tmp_project_creator[0]","attribute":["org_id"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.firewall_rules.google_compute_firewall.rules","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.optional_group.google_cloud_identity_group.group","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","attribute":["location"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["display_name"]},{"resource":"module.build_terraform_image.random_id.cache[0]","attribute":["hex"]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"bootstrap\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.optional_group.google_cloud_identity_group.group","attribute":["group_key",0,"id"]},{"resource":"module.tf_workspace.module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_tags_tag_binding.bindings","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["account_id"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.firewall_rules.google_compute_firewall.rules_ingress_egress","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_shared_vpc_host_project.shared_vpc_host","attribute":[]},{"resource":"module.tf_private_pool.google_cloudbuild_worker_pool.private_pool","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.essential_contacts.google_essential_contacts_contact.contact","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"google_service_account.terraform-env-sa[\"env\"]","attribute":["email"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"bootstrap\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_workspace.module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","attribute":["name"]},{"resource":"module.tf_private_pool.random_string.suffix","attribute":["result"]},{"resource":"module.build_terraform_image.null_resource.run_destroy_command","attribute":[]},{"resource":"module.tf_cloud_builder.module.bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace.google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.build_terraform_image.null_resource.additional_components","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.shared_vpc_access.data.google_project.service_project[0]","attribute":["number"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.routes.google_compute_route.route","attribute":[]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["address"]},{"resource":"module.seed_bootstrap.module.seed_project.module.budget.google_billing_budget.budget","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["self_link"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["project"]},{"resource":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules_ingress_egress","attribute":[]},{"resource":"data.google_project.seed_project","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_storage_bucket.project_bucket","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.budget.data.google_project.project","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_source.google_sourcerepo_repository.gcp_repo","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","attribute":["name"]},{"resource":"module.seed_bootstrap.google_service_account.org_terraform[0]","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.tf_cloud_builder.google_cloud_scheduler_job.trigger_workflow","attribute":["id"]},{"resource":"module.tf_workspace.google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","attribute":["project_id"]},{"resource":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"google_service_account.terraform-env-sa[\"bootstrap\"]","attribute":["email"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace.module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":[]},{"resource":"time_sleep.cloud_builder","attribute":[]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_cloud_builder.module.bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.gcp_projects_state_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"google_service_account.terraform-env-sa","attribute":[]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.bootstrap_csr_repo.null_resource.gcloud_auth_service_account_key_file","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["prefix_length"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["account_id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_storage_bucket.project_bucket","attribute":[]},{"resource":"module.seed_bootstrap.data.google_storage_project_service_account.gcs_account","attribute":["email_address"]},{"resource":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.build_terraform_image.null_resource.gcloud_auth_service_account_key_file","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services","attribute":[]},{"resource":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.tf_workspace.module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_cloud_builder.module.bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.google_service_networking_connection.worker_pool_conn[0]","attribute":["peering"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.essential_contacts.google_essential_contacts_contact.contact","attribute":[]},{"resource":"module.build_terraform_image.data.external.env_override[0]","attribute":["result","download"]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]}],"timestamp":"2025-08-06T13:00:27Z"} diff --git a/0-bootstrap/bootstrap.tfplan b/0-bootstrap/bootstrap.tfplan new file mode 100644 index 0000000000000000000000000000000000000000..39180199f33a3760a602d84d10e7f19d22271220 GIT binary patch literal 281042 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�?S>tyjyNC2o_ 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 z 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 literal 0 HcmV?d00001 diff --git a/0-bootstrap/terraform.example.tfvars b/0-bootstrap/terraform.example.tfvars deleted file mode 100644 index 9b85c95fa..000000000 --- a/0-bootstrap/terraform.example.tfvars +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Copyright 2023 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -org_id = "REPLACE_ME" # format "000000000000" - -billing_account = "REPLACE_ME" # format "000000-000000-000000" - -// For enabling the automatic groups creation, uncoment the -// variables and update the values with the group names -groups = { - # create_required_groups = false # Change to true to create the required_groups - # create_optional_groups = false # Change to true to create the optional_groups - # billing_project = "REPLACE_ME" # Fill to create required or optional groups - required_groups = { - group_org_admins = "REPLACE_ME" # example "gcp-organization-admins@example.com" - group_billing_admins = "REPLACE_ME" # example "gcp-billing-admins@example.com" - billing_data_users = "REPLACE_ME" # example "gcp-billing-data@example.com" - audit_data_users = "REPLACE_ME" # example "gcp-audit-data@example.com" - } - # optional_groups = { - # gcp_security_reviewer = "" #"gcp_security_reviewer_local_test@example.com" - # gcp_network_viewer = "" #"gcp_network_viewer_local_test@example.com" - # gcp_scc_admin = "" #"gcp_scc_admin_local_test@example.com" - # gcp_global_secrets_admin = "" #"gcp_global_secrets_admin_local_test@example.com" - # gcp_kms_admin = "" #"gcp_kms_admin_local_test@example.com" - # } -} - -default_region = "us-central1" -default_region_2 = "us-west1" -default_region_gcs = "US" -default_region_kms = "us" - -# Optional - for an organization with existing projects or for development/validation. -# Uncomment this variable to place all the example foundation resources under -# the provided folder instead of the root organization. -# The variable value is the numeric folder ID -# The folder must already exist. -# parent_folder = "01234567890" - - -/* ---------------------------------------- - Specific to github_bootstrap - ---------------------------------------- */ -# Un-comment github_bootstrap and its outputs if you want to use GitHub Actions instead of Cloud Build -# gh_repos = { -# owner = "YOUR-GITHUB-USER-OR-ORGANIZATION", -# bootstrap = "YOUR-BOOTSTRAP-REPOSITORY", -# organization = "YOUR-ORGANIZATION-REPOSITORY", -# environments = "YOUR-ENVIRONMENTS-REPOSITORY", -# networks = "YOUR-NETWORKS-REPOSITORY", -# projects = "YOUR-PROJECTS-REPOSITORY", -# } -# -# to prevent saving the `gh_token` in plain text in this file, -# export the GitHub fine grained access token in the command line -# as an environment variable before running terraform. -# Run the following commnad in your shell: -# export TF_VAR_gh_token="YOUR-FINE-GRAINED-ACCESS-TOKEN" - - -/* ---------------------------------------- - Specific to jenkins_bootstrap module - ---------------------------------------- */ -# Un-comment the jenkins_bootstrap module and its outputs if you want to use Jenkins instead of Cloud Build -# jenkins_agent_gce_subnetwork_cidr_range = "172.16.1.0/24" -# -# jenkins_agent_gce_private_ip_address = "172.16.1.6" -# -# jenkins_agent_gce_ssh_pub_key = "ssh-rsa [KEY_VALUE] [USERNAME]" -# -# jenkins_agent_sa_email = "jenkins-agent-gce" # service_account_prefix will be added -# -# jenkins_controller_subnetwork_cidr_range = ["10.1.0.6/32"] -# -# nat_bgp_asn = "64514" -# -# vpn_shared_secret = "shared_secret" -# -# on_prem_vpn_public_ip_address = "" -# -# on_prem_vpn_public_ip_address2 = "" -# -# router_asn = "64515" -# -# bgp_peer_asn = "64513" -# -# tunnel0_bgp_peer_address = "169.254.1.1" -# -# tunnel0_bgp_session_range = "169.254.1.2/30" -# -# tunnel1_bgp_peer_address = "169.254.2.1" -# -# tunnel1_bgp_session_range = "169.254.2.2/30" - -/* ---------------------------------------- - Specific to gitlab_bootstrap - ---------------------------------------- */ -# Un-comment gitlab_bootstrap and its outputs if you want to use GitLab CI/CD instead of Cloud Build -# gl_repos = { -# owner = "YOUR-GITLAB-USER-OR-GROUP", -# bootstrap = "YOUR-BOOTSTRAP-REPOSITORY", -# organization = "YOUR-ORGANIZATION-REPOSITORY", -# environments = "YOUR-ENVIRONMENTS-REPOSITORY", -# networks = "YOUR-NETWORKS-REPOSITORY", -# projects = "YOUR-PROJECTS-REPOSITORY", -# cicd_runner = "YOUR-CICD-RUNNER-REPOSITORY", -# } -# -# to prevent saving the `gitlab_token` in plain text in this file, -# export the GitLab access token in the command line -# as an environment variable before running terraform. -# Run the following commnad in your shell: -# export TF_VAR_gitlab_token="YOUR-ACCESS-TOKEN" - -/* ---------------------------------------- - Specific to tfc_bootstrap - ---------------------------------------- */ -// Un-comment tfc_bootstrap and its outputs if you want to use Terraform Cloud instead of Cloud Build -// Format expected: REPO-OWNER/REPO-NAME -# vcs_repos = { -# owner = "YOUR-VCS-USER-OR-ORGANIZATION", -# bootstrap = "YOUR-BOOTSTRAP-REPOSITORY", -# organization = "YOUR-ORGANIZATION-REPOSITORY", -# environments = "YOUR-ENVIRONMENTS-REPOSITORY", -# networks = "YOUR-NETWORKS-REPOSITORY", -# projects = "YOUR-PROJECTS-REPOSITORY", -# } -# tfc_org_name = "REPLACE_ME" - - -// Set this to true if you want to use Terraform Cloud Agents instead of Terraform Cloud remote runner -// If true, a private Autopilot GKE cluster will be created in your GCP account to be used as Terraform Cloud Agents -// More info about Agents on: https://developer.hashicorp.com/terraform/cloud-docs/agents - -# enable_tfc_cloud_agents = false - -// to prevent saving the `tfc_token` in plain text in this file, -// export the Terraform Cloud token in the command line -// as an environment variable before running terraform. -// Run the following commnad in your shell: -// export TF_VAR_tfc_token="YOUR-TFC-TOKEN" - -// For VCS connection based in OAuth: (GitHub OAuth/GitHub Enterprise/Gitlab.com/GitLab Enterprise or Community Edition) -// to prevent saving the `vcs_oauth_token_id` in plain text in this file, -// export the Terraform Cloud VCS Connection OAuth token ID in the command line -// as an environment variable before running terraform. - -// Note: you should be able to copy `OAuth Token ID` (vcs_oauth_token_id) in TFC console: -// https://app.terraform.io/app/YOUR-TFC-ORGANIZATION/settings/version-control - -// Run the following commnad in your shell: -// export TF_VAR_vcs_oauth_token_id="YOUR-VCS-OAUTH-TOKEN-ID" - -// For GitHub OAuth see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/github -// For GitHub Enterprise see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/github-enterprise -// For GitLab.com see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/gitlab-com -// For GitLab EE/CE see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/gitlab-eece From 1a638eb8f09a29c8c50b8a467b2fcd9fbcced418 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 6 Aug 2025 11:40:36 -0300 Subject: [PATCH 029/114] rm enforce_vpc-sc variable from service_control.tf --- 1-org/envs/shared/service_control.tf | 31 ++++------------------------ 1-org/envs/shared/variables.tf | 6 ------ 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index e07268f9e..ced7124ac 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -158,7 +158,7 @@ locals { }) : tostring(v) ] - projects = var.enable_hub_and_spoke ? (concat([ + projects = (concat([ local.seed_project_number, module.org_audit_logs.project_number, module.org_billing_export.project_number, @@ -166,31 +166,9 @@ locals { module.org_secrets.project_number, module.interconnect.project_number, module.scc_notifications.project_number, - module.network_hub.project_number, - ], local.shared_vpc_projects_numbers - )) : (concat([ - local.seed_project_number, - module.org_audit_logs.project_number, - module.org_billing_export.project_number, - module.common_kms.project_number, - module.org_secrets.project_number, - module.interconnect.project_number, - module.scc_notifications.project_number, ], local.shared_vpc_projects_numbers)) - project_keys = var.enable_hub_and_spoke ? [ - "prj-org-seed", - "prj-org-audit", - "prj-org-billing", - "prj-org-kms", - "prj-org-secrets", - "prj-org-interconnect", - "prj-org-scc", - "prj-net-hub", - "prj-net-p-svpc", - "prj-net-d-svpc", - "prj-net-n-svpc", - ] : [ + project_keys = [ "prj-org-seed", "prj-org-audit", "prj-org-billing", @@ -575,11 +553,10 @@ module "service_control" { ], var.perimeter_additional_members)) resources_dry_run = concat(values(local.projects_map), var.resources_dry_run) resource_keys_dry_run = local.project_keys - ingress_policies = var.enforce_vpcsc ? distinct(concat(var.ingress_policies, local.required_ingress_rules)) : tolist([]) - ingress_policies_dry_run = !var.enforce_vpcsc ? distinct(concat(var.ingress_policies_dry_run, local.required_ingress_rules_dry_run)) : tolist([]) + ingress_policies = distinct(concat(var.ingress_policies, local.required_ingress_rules)) + ingress_policies_dry_run = distinct(concat(var.ingress_policies_dry_run, local.required_ingress_rules_dry_run)) egress_policies = distinct(concat(var.egress_policies, local.required_egress_rules)) egress_policies_dry_run = distinct(concat(var.egress_policies_dry_run, local.required_egress_rules_dry_run)) - enforce_vpcsc = var.enforce_vpcsc depends_on = [ time_sleep.wait_projects diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index 5f368e27e..486c2966a 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -339,9 +339,3 @@ variable "resources_dry_run" { type = list(string) default = [] } - -variable "enforce_vpcsc" { - description = "Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases." - type = bool - default = false -} From bb808b3235762a6da61d5a26a19e2370056bb9a9 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 6 Aug 2025 11:41:15 -0300 Subject: [PATCH 030/114] add directional policies variables keys --- 1-org/modules/service_control/main.tf | 9 +++++--- 1-org/modules/service_control/variables.tf | 24 ++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/1-org/modules/service_control/main.tf b/1-org/modules/service_control/main.tf index a1f004910..629880fc4 100644 --- a/1-org/modules/service_control/main.tf +++ b/1-org/modules/service_control/main.tf @@ -46,9 +46,8 @@ module "access_level_dry_run" { } module "regular_service_perimeter" { - source = "git::https://github.com/mariammartins/terraform-google-vpc-service-controls.git//modules/regular_service_perimeter?ref=fix-ingress-rules" - # source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" - # version = "~> 7.1.2" + source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" + version = "~> 7.1.2" policy = var.access_context_manager_policy_id perimeter_name = local.perimeter_name @@ -61,7 +60,9 @@ module "regular_service_perimeter" { restricted_services = var.enforce_vpcsc ? var.restricted_services : [] vpc_accessible_services = var.enforce_vpcsc ? ["*"] : [] ingress_policies = var.enforce_vpcsc ? var.ingress_policies : [] + ingress_policies_keys = var.enforce_vpcsc ? var.ingress_policies_keys : [] egress_policies = var.enforce_vpcsc ? var.egress_policies : [] + egress_policies_keys = var.enforce_vpcsc ? var.egress_policies_keys : [] # configurations for a perimeter in dry run mode. resources_dry_run = var.resources_dry_run @@ -70,7 +71,9 @@ module "regular_service_perimeter" { restricted_services_dry_run = var.restricted_services_dry_run vpc_accessible_services_dry_run = ["*"] ingress_policies_dry_run = var.ingress_policies_dry_run + ingress_policies_keys_dry_run = var.ingress_policies_keys_dry_run egress_policies_dry_run = var.egress_policies_dry_run + egress_policies_keys_dry_run = var.egress_policies_keys_dry_run } resource "time_sleep" "wait_vpc_sc_propagation" { diff --git a/1-org/modules/service_control/variables.tf b/1-org/modules/service_control/variables.tf index 1236660be..53d5f0923 100644 --- a/1-org/modules/service_control/variables.tf +++ b/1-org/modules/service_control/variables.tf @@ -168,3 +168,27 @@ variable "resource_keys_dry_run" { type = list(string) default = null } + +variable "ingress_policies_keys" { + description = "A list of keys to use for the Terraform state. The order should correspond to var.ingress_policies and the keys must not be dynamically computed. If `null`, var.ingress_policies will be used as keys." + type = list(string) + default = null +} + +variable "egress_policies_keys" { + description = "A list of keys to use for the Terraform state. The order should correspond to var.egress_policies and the keys must not be dynamically computed. If `null`, var.egress_policies will be used as keys." + type = list(string) + default = null +} + +variable "ingress_policies_keys_dry_run" { + description = "(Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.ingress_policies_dry_run and the keys must not be dynamically computed. If `null`, var.ingress_policies_dry_run will be used as keys." + type = list(string) + default = null +} + +variable "egress_policies_keys_dry_run" { + description = "(Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.egress_policies_dry_run and the keys must not be dynamically computed. If `null`, var.egress_policies_dry_run will be used as keys." + type = list(string) + default = null +} From 1204991ff5b68cdbe2c047953a34bfdac53d215b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 6 Aug 2025 14:27:19 -0300 Subject: [PATCH 031/114] updt cloud function source --- 1-org/modules/cai-monitoring/main.tf | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/1-org/modules/cai-monitoring/main.tf b/1-org/modules/cai-monitoring/main.tf index 353af6f0c..77d391902 100644 --- a/1-org/modules/cai-monitoring/main.tf +++ b/1-org/modules/cai-monitoring/main.tf @@ -141,8 +141,9 @@ resource "google_scc_source" "cai_monitoring" { // Cloud Function module "cloud_function" { - source = "GoogleCloudPlatform/cloud-functions/google" - version = "~> 0.6" + source = "git::https://github.com/GoogleCloudPlatform/terraform-google-cloud-functions.git?ref=release-please--branches--main" + # source = "GoogleCloudPlatform/cloud-functions/google" + # version = "~> 0.6" function_name = "caiMonitoring" description = "Check on the Organization for members (users, groups and service accounts) that contains the IAM roles listed." From 3e40d6fafe264049fde3ce3310cb201fed96bb02 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 6 Aug 2025 14:30:14 -0300 Subject: [PATCH 032/114] fix direcitional policies with maps --- 1-org/envs/shared/service_control.tf | 37 +++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index ced7124ac..d501708e4 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -186,6 +186,31 @@ locals { [for p in local.projects : "${p}"] ) + ingress_policies_keys_dry_run = ["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"] + egress_policies_keys_dry_run = ["seed_to_cicd", "org_sa_to_scc", "user_to_seed"] + ingress_policies_keys = ["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"] + egress_policies_keys = ["seed_to_cicd", "org_sa_to_scc", "user_to_seed"] + + ingress_policies_dry_run_map = zipmap( + local.ingress_policies_keys_dry_run, + [for r in local.required_ingress_rules_dry_run : "${r}"] + ) + + egress_policies_dry_run_map = zipmap( + local.egress_policies_keys_dry_run, + [for r in local.required_egress_rules_dry_run : "${r}"] + ) + + ingress_policies_map = zipmap( + local.ingress_policies_keys, + [for r in local.required_ingress_rules_dry_run : "${r}"] + ) + + egress_policies_map = zipmap( + local.egress_policies_keys, + [for r in local.required_egress_rules_dry_run : "${r}"] + ) + required_egress_rules_dry_run = [ { from = { @@ -553,10 +578,14 @@ module "service_control" { ], var.perimeter_additional_members)) resources_dry_run = concat(values(local.projects_map), var.resources_dry_run) resource_keys_dry_run = local.project_keys - ingress_policies = distinct(concat(var.ingress_policies, local.required_ingress_rules)) - ingress_policies_dry_run = distinct(concat(var.ingress_policies_dry_run, local.required_ingress_rules_dry_run)) - egress_policies = distinct(concat(var.egress_policies, local.required_egress_rules)) - egress_policies_dry_run = distinct(concat(var.egress_policies_dry_run, local.required_egress_rules_dry_run)) + ingress_policies_keys_dry_run = local.ingress_policies_keys_dry_run + egress_policies_keys_dry_run = local.egress_policies_keys_dry_run + ingress_policies_keys = local.ingress_policies_keys + egress_policies_keys = local.egress_policies_keys_dry_run + ingress_policies = distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) + ingress_policies_dry_run = distinct(concat(values(local.ingress_policies_dry_run_map), var.ingress_policies_dry_run, local.required_ingress_rules_dry_run)) + egress_policies = distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) + egress_policies_dry_run = distinct(concat(values(local.egress_policies_dry_run_map), var.egress_policies_dry_run, local.required_egress_rules_dry_run)) depends_on = [ time_sleep.wait_projects From a2fd29fac4d6760e3a6c537beab7a8eab0ae526b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 6 Aug 2025 15:02:45 -0300 Subject: [PATCH 033/114] add outputs 1-org --- 1-org/envs/shared/README.md | 9 +++++++- 1-org/envs/shared/outputs.tf | 45 ++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 65dcc71e7..e2db0573e 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -16,7 +16,6 @@ | enable\_kms\_key\_usage\_tracking | Enable KMS centralized key usage tracking system. | `bool` | `true` | no | | enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context. | `bool` | `true` | no | | enforce\_allowed\_worker\_pools | Whether to enforce the organization policy restriction on allowed worker pools for Cloud Build. | `bool` | `false` | no | -| enforce\_vpcsc | Enable the enforced mode for VPC Service Controls. It is not recommended to enable VPC-SC on the first run deploying your foundation. Review [best practices for enabling VPC Service Controls](https://cloud.google.com/vpc-service-controls/docs/enable), then only enforce the perimeter after you have analyzed the access patterns in your dry-run perimeter and created the necessary exceptions for your use cases. | `bool` | `false` | no | | essential\_contacts\_domains\_to\_allow | .The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes | | essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no | | folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | no | @@ -42,6 +41,9 @@ | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | +| access\_level\_name | Access context manager access level name | +| access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | | billing\_sink\_names | The name of the sinks under billing account level. | | build\_service\_account | Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container. | | cai\_monitoring\_artifact\_registry | CAI Monitoring Cloud Function Artifact Registry name. | @@ -51,8 +53,12 @@ | common\_folder\_name | The common folder name | | common\_kms\_project\_id | The org Cloud Key Management Service (KMS) project ID | | domains\_to\_allow | The list of domains to allow users from in IAM. | +| enforce\_vpcsc | The mode of VPC Service Controls. | | interconnect\_project\_id | The Dedicated Interconnect project ID | | interconnect\_project\_number | The Dedicated Interconnect project number | +| internal\_project\_log\_export | The service account that logging uses to write log entries to the destination. | +| log\_export | The service account that logging uses to write log entries to the destination. | +| log\_export\_billing | The service account that logging uses to write log entries to the destination. | | logs\_export\_project\_linked\_dataset\_name | The resource name of the Log Bucket linked BigQuery dataset for the project destination. | | logs\_export\_project\_logbucket\_name | The resource name for the Log Bucket created for the project destination. | | logs\_export\_pubsub\_topic | The Pub/Sub topic for destination of log exports | @@ -68,6 +74,7 @@ | parent\_resource\_type | The parent resource type | | scc\_notification\_name | Name of SCC Notification | | scc\_notifications\_project\_id | The SCC notifications project ID | +| service\_perimeter\_name | Access context manager service perimeter name | | shared\_vpc\_projects | Shared VPC Projects info grouped by environment (development, nonproduction, production). | | tags | Tag Values to be applied on next steps. | diff --git a/1-org/envs/shared/outputs.tf b/1-org/envs/shared/outputs.tf index 87f91e8b2..b1ec93863 100644 --- a/1-org/envs/shared/outputs.tf +++ b/1-org/envs/shared/outputs.tf @@ -153,3 +153,48 @@ output "build_service_account" { description = "Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container." value = google_service_account.cai_monitoring_builder[0].email } + +output "enforce_vpcsc" { + value = module.service_control.enforce_vpcsc + description = "The mode of VPC Service Controls." +} + +output "service_perimeter_name" { + value = module.service_control.service_perimeter_name + description = "Access context manager service perimeter name" +} + +output "access_level_name" { + value = module.service_control.access_level_name + description = "Access context manager access level name" +} + +output "access_level_name_dry_run" { + value = module.service_control.access_level_name_dry_run + description = "Access context manager access level name for the dry-run perimeter" +} + +output "access_context_manager_policy_id" { + value = local.access_context_manager_policy_id + description = "Access Context Manager Policy ID." +} + +output "build_service_account" { + description = "Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container." + value = google_service_account.cai_monitoring_builder[0].email +} + +output "log_export_billing" { + description = "The service account that logging uses to write log entries to the destination." + value = module.logs_export.log_export_billing +} + +output "log_export" { + description = "The service account that logging uses to write log entries to the destination." + value = module.logs_export.log_export +} + +output "internal_project_log_export" { + description = "The service account that logging uses to write log entries to the destination." + value = module.logs_export.internal_project_log_export +} From 7af8f37621ab07e96f56989f13bb5947ea351a80 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 6 Aug 2025 16:44:57 -0300 Subject: [PATCH 034/114] add network_hub in projects list and keys --- 1-org/envs/shared/service_control.tf | 29 ++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index d501708e4..a73ed130f 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -158,7 +158,16 @@ locals { }) : tostring(v) ] - projects = (concat([ + projects = var.enable_hub_and_spoke ? (concat([ + local.seed_project_number, + module.org_audit_logs.project_number, + module.org_billing_export.project_number, + module.common_kms.project_number, + module.org_secrets.project_number, + module.interconnect.project_number, + module.network_hub.project_number, + module.scc_notifications.project_number, + ], local.shared_vpc_projects_numbers)) : (concat([ local.seed_project_number, module.org_audit_logs.project_number, module.org_billing_export.project_number, @@ -168,7 +177,18 @@ locals { module.scc_notifications.project_number, ], local.shared_vpc_projects_numbers)) - project_keys = [ + project_keys = var.enable_hub_and_spoke ? [ + "prj-org-seed", + "prj-org-audit", + "prj-org-billing", + "prj-org-kms", + "prj-org-secrets", + "prj-org-interconnect", + "prj-org-scc", + "prj-net-p-svpc", + "prj-net-d-svpc", + "prj-net-n-svpc", + ] : [ "prj-org-seed", "prj-org-audit", "prj-org-billing", @@ -176,6 +196,7 @@ locals { "prj-org-secrets", "prj-org-interconnect", "prj-org-scc", + "prj-net-hub-svpc", "prj-net-p-svpc", "prj-net-d-svpc", "prj-net-n-svpc", @@ -576,8 +597,8 @@ module "service_control" { "serviceAccount:${local.organization_service_account}", "serviceAccount:${local.environment_service_account}", ], var.perimeter_additional_members)) - resources_dry_run = concat(values(local.projects_map), var.resources_dry_run) - resource_keys_dry_run = local.project_keys + resources_dry_run = concat(values(local.projects_map), var.resources_dry_run) + resource_keys_dry_run = local.project_keys ingress_policies_keys_dry_run = local.ingress_policies_keys_dry_run egress_policies_keys_dry_run = local.egress_policies_keys_dry_run ingress_policies_keys = local.ingress_policies_keys From 3bde87017d61f93e70c793520598202cd432e8b0 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 14:12:12 -0300 Subject: [PATCH 035/114] fix README, service_control.tf and rm bootstrap files --- 0-bootstrap/README.md | 4 ++-- 0-bootstrap/bootstrap.json | 1 - 0-bootstrap/bootstrap.tfplan | Bin 281042 -> 0 bytes 1-org/envs/shared/service_control.tf | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) delete mode 100644 0-bootstrap/bootstrap.json delete mode 100644 0-bootstrap/bootstrap.tfplan diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md index 02f1e2958..87baa2a0b 100644 --- a/0-bootstrap/README.md +++ b/0-bootstrap/README.md @@ -224,7 +224,7 @@ The following steps introduce the steps to deploy with Cloud Build Alternatively 1. Use the helper script [validate-requirements.sh](../scripts/validate-requirements.sh) to validate your environment: ```bash - ../scripts/validate-requirements.sh -o 1055058813388 -b 01AAD1-616217-97513A -u mariamartins@clsecteam.com + ../scripts/validate-requirements.sh -o -b -u ``` **Note:** The script is not able to validate if the user is in a Cloud Identity or Google Workspace group with the required roles. @@ -241,7 +241,7 @@ The following steps introduce the steps to deploy with Cloud Build Alternatively 1. Run the following commands and check for violations: ```bash - export VET_PROJECT_ID=deployer-foundation + export VET_PROJECT_ID=A-VALID-PROJECT-ID terraform show -json bootstrap.tfplan > bootstrap.json gcloud beta terraform vet bootstrap.json --policy-library="../policy-library" --project ${VET_PROJECT_ID} ``` diff --git a/0-bootstrap/bootstrap.json b/0-bootstrap/bootstrap.json deleted file mode 100644 index 96c0e258b..000000000 --- a/0-bootstrap/bootstrap.json +++ /dev/null @@ -1 +0,0 @@ -{"format_version":"1.2","terraform_version":"1.5.7","variables":{"attribute_condition":{"value":null},"billing_account":{"value":"01AAD1-616217-97513A"},"bucket_force_destroy":{"value":false},"bucket_prefix":{"value":"bkt"},"bucket_tfstate_kms_force_destroy":{"value":false},"default_region":{"value":"us-central1"},"default_region_2":{"value":"us-west1"},"default_region_gcs":{"value":"US"},"default_region_kms":{"value":"us"},"folder_deletion_protection":{"value":"true"},"folder_prefix":{"value":"fldr"},"groups":{"value":{"required_groups":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"}}},"initial_group_config":{"value":"WITH_INITIAL_OWNER"},"org_id":{"value":"1055058813388"},"org_policy_admin_role":{"value":false},"parent_folder":{"value":"49822046027"},"project_deletion_policy":{"value":"PREVENT"},"project_prefix":{"value":"prj"},"workflow_deletion_protection":{"value":true}},"planned_values":{"outputs":{"bootstrap_step_terraform_service_account_email":{"sensitive":false},"cloud_build_peered_network_id":{"sensitive":false},"cloud_build_private_worker_pool_id":{"sensitive":false},"cloud_build_worker_peered_ip_range":{"sensitive":false,"type":"string","value":"192.168.0.0/24"},"cloud_build_worker_range_id":{"sensitive":false},"cloud_builder_artifact_repo":{"sensitive":false},"cloudbuild_project_id":{"sensitive":false},"cloudbuild_project_number":{"sensitive":false},"common_config":{"sensitive":false},"csr_repos":{"sensitive":false},"environment_step_terraform_service_account_email":{"sensitive":false},"gcs_bucket_cloudbuild_artifacts":{"sensitive":false},"gcs_bucket_cloudbuild_logs":{"sensitive":false},"gcs_bucket_tfstate":{"sensitive":false},"networks_step_terraform_service_account_email":{"sensitive":false},"optional_groups":{"sensitive":false,"type":["map","string"],"value":{"gcp_global_secrets_admin":"","gcp_kms_admin":"","gcp_network_viewer":"","gcp_scc_admin":"","gcp_security_reviewer":""}},"organization_step_terraform_service_account_email":{"sensitive":false},"parent_id":{"sensitive":false,"type":"string","value":"folder-49822046027"},"projects_gcs_bucket_tfstate":{"sensitive":false},"projects_step_terraform_service_account_email":{"sensitive":false},"required_groups":{"sensitive":false,"type":["map","string"],"value":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"}},"seed_project_id":{"sensitive":false},"seed_project_number":{"sensitive":false}},"root_module":{"resources":[{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"data.google_project.seed_project","mode":"data","type":"google_project","name":"seed_project","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"bootstrap\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"env\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"net\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"org\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"proj\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_account_sink","mode":"managed","type":"google_billing_account_iam_member","name":"billing_account_sink","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/logging.configWriter"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.billing_admin_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_billing_account_iam_member.tf_billing_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"google_folder.bootstrap","mode":"managed","type":"google_folder","name":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"deletion_protection":true,"display_name":"fldr-bootstrap","parent":"folders/49822046027","tags":null,"timeouts":null},"sensitive_values":{}},{"address":"google_project_service_identity.workflows_identity","mode":"managed","type":"google_project_service_identity","name":"workflows_identity","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"service":"workflows.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"bootstrap\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-bootstrap","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Bootstrap SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"env\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-env","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Environment SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"net\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-net","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Network SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"org\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-org","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Organization SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_service_account.terraform-env-sa[\"proj\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"sa-terraform-proj","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Projects SA. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"google_sourcerepo_repository_iam_member.member[\"bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"env\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"env","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"net\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"net","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"org\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"google_sourcerepo_repository_iam_member.member[\"proj\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":2,"values":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"sensitive_values":{}},{"address":"time_sleep.cloud_builder","mode":"managed","type":"time_sleep","name":"cloud_builder","provider_name":"registry.terraform.io/hashicorp/time","schema_version":0,"values":{"create_duration":"30s","destroy_duration":null,"triggers":null},"sensitive_values":{}}],"child_modules":[{"resources":[{"address":"module.bootstrap_csr_repo.null_resource.run_command[0]","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"create_cmd_entrypoint":"./scripts/push-to-repo.sh","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"ad3634e17109216cf99cbd7242475359"}},"sensitive_values":{"triggers":{}}},{"address":"module.bootstrap_csr_repo.null_resource.run_destroy_command[0]","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin"}},"sensitive_values":{"triggers":{}}}],"address":"module.bootstrap_csr_repo"},{"resources":[{"address":"module.bootstrap_projects_remove_editor[\"cicd\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"members":null,"role":"roles/editor"},"sensitive_values":{"condition":[]}}],"address":"module.bootstrap_projects_remove_editor[\"cicd\"]"},{"resources":[{"address":"module.bootstrap_projects_remove_editor[\"seed\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"members":null,"role":"roles/editor"},"sensitive_values":{"condition":[]}}],"address":"module.bootstrap_projects_remove_editor[\"seed\"]"},{"resources":[{"address":"module.build_terraform_image.null_resource.module_depends_on[0]","mode":"managed","type":"null_resource","name":"module_depends_on","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"value":"1"}},"sensitive_values":{"triggers":{}}},{"address":"module.build_terraform_image.null_resource.run_command[0]","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"create_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"7f22bf39aaf5ce5980111c3587bef5b5","terraform_version":"1.5.7"}},"sensitive_values":{"triggers":{}}},{"address":"module.build_terraform_image.null_resource.run_destroy_command[0]","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","schema_version":0,"values":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","terraform_version":"1.5.7"}},"sensitive_values":{"triggers":{}}}],"address":"module.build_terraform_image"},{"resources":[{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/artifactregistry.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/artifactregistry.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.builds.editor\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.builds.editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.workerPoolOwner\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.workerPoolOwner","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolOwner"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudscheduler.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudscheduler.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudscheduler.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/compute.networkAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/compute.networkAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/dns.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/dns.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.workloadIdentityPoolAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.workloadIdentityPoolAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.workloadIdentityPoolAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/source.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/source.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/source.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/workflows.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/workflows.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/workflows.admin"},"sensitive_values":{"condition":[]}}],"address":"module.cicd_project_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.gcp_projects_state_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.gcp_projects_state_bucket"},{"resources":[{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/assuredworkloads.admin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/assuredworkloads.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/assuredworkloads.admin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"env\"]"},{"resources":[{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/compute.xpnAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/compute.xpnAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"net\"]"},{"resources":[{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/cloudasset.owner\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudasset.owner","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/cloudasset.owner"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/essentialcontacts.admin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/essentialcontacts.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/essentialcontacts.admin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/logging.configWriter\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/logging.configWriter","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/logging.configWriter"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/orgpolicy.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/orgpolicy.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/orgpolicy.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationViewer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationViewer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationViewer"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.notificationConfigEditor\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.notificationConfigEditor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.notificationConfigEditor"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.sourcesEditor\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.sourcesEditor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.sourcesEditor"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"org\"]"},{"resources":[{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/cloudkms.admin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/cloudkms.admin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}}],"address":"module.org_iam_member[\"proj\"]"},{"resources":[{"address":"module.parent_iam_member[\"bootstrap\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.parent_iam_member[\"env\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"env\"]"},{"resources":[{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityPolicyAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityPolicyAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityPolicyAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityResourceAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityResourceAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityResourceAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.securityAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.securityAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.securityAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/dns.admin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/dns.admin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderViewer\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderViewer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderViewer"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"net\"]"},{"resources":[{"address":"module.parent_iam_member[\"org\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"org\"]"},{"resources":[{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/artifactregistry.admin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/artifactregistry.admin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.xpnAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/compute.xpnAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/iam.serviceAccountAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/iam.serviceAccountAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.parent_iam_member[\"proj\"]"},{"resources":[{"address":"module.seed_bootstrap.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.google_folder_iam_binding.project_creator[0]","mode":"managed","type":"google_folder_iam_binding","name":"project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.projectCreator"},"sensitive_values":{"condition":[],"members":[]}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_service_account_user[0]","mode":"managed","type":"google_folder_iam_member","name":"org_admin_service_account_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_serviceusage_consumer[0]","mode":"managed","type":"google_folder_iam_member","name":"org_admin_serviceusage_consumer","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/serviceusage.serviceUsageConsumer"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_folder_iam_member.tmp_project_creator[0]","mode":"managed","type":"google_folder_iam_member","name":"tmp_project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/resourcemanager.projectCreator"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_organization_iam_binding.billing_creator","mode":"managed","type":"google_organization_iam_binding","name":"billing_creator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"members":["group:billing_admin_duda_foundation@clsecteam.com"],"org_id":"1055058813388","role":"roles/billing.creator"},"sensitive_values":{"condition":[],"members":[false]}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/billing.user\"]","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/billing.user","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/billing.user"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/resourcemanager.organizationAdmin\"]","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_billing_admin","mode":"managed","type":"google_organization_iam_member","name":"org_billing_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:billing_admin_duda_foundation@clsecteam.com","org_id":"1055058813388","role":"roles/billing.admin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.google_storage_bucket.org_terraform_state","mode":"managed","type":"google_storage_bucket","name":"org_terraform_state","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"requester_pays":null,"retention_policy":[],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[],"terraform_labels":{},"versioning":[{}],"website":[]}},{"address":"module.seed_bootstrap.google_storage_bucket_iam_member.orgadmins_state_iam[0]","mode":"managed","type":"google_storage_bucket_iam_member","name":"orgadmins_state_iam","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_bootstrap.random_id.suffix","mode":"managed","type":"random_id","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":0,"values":{"byte_length":2,"keepers":null,"prefix":null},"sensitive_values":{}}],"address":"module.seed_bootstrap","child_modules":[{"address":"module.seed_bootstrap.module.seed_project","child_modules":[{"resources":[{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"name":"prj-b-seed","tags":null,"terraform_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"sensitive_values":{"effective_labels":{},"labels":{},"terraform_labels":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"sensitive_values":{"service_accounts":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_resource_manager_lien.lien[0]","mode":"managed","type":"google_resource_manager_lien","name":"lien","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"origin":"project-factory","reason":"Project Factory lien","restrictions":["resourcemanager.projects.delete"],"timeouts":null},"sensitive_values":{"restrictions":[false]}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":0,"values":{"byte_length":2,"keepers":null,"prefix":null},"sensitive_values":{}}],"address":"module.seed_bootstrap.module.seed_project.module.project-factory","child_modules":[{"resources":[{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"accesscontextmanager.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"accesscontextmanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"accesscontextmanager.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"assuredworkloads.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"assuredworkloads.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"assuredworkloads.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudasset.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudasset.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudasset.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudkms.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudkms.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudkms.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"essentialcontacts.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"essentialcontacts.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"essentialcontacts.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iamcredentials.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"iamcredentials.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iamcredentials.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"monitoring.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"monitoring.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"monitoring.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"pubsub.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"pubsub.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"pubsub.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"securitycenter.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"securitycenter.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"securitycenter.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"sensitive_values":{}}],"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services"}]}]},{"resources":[{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key[0]","mode":"managed","type":"google_kms_crypto_key","name":"key","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"effective_labels":{"goog-terraform-provisioned":"true"},"import_only":false,"labels":null,"name":"prj-key","purpose":"ENCRYPT_DECRYPT","rotation_period":"7776000s","skip_initial_version_creation":false,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"version_template":[{"algorithm":"GOOGLE_SYMMETRIC_ENCRYPTION","protection_level":"SOFTWARE"}]},"sensitive_values":{"effective_labels":{},"primary":[],"terraform_labels":{},"version_template":[{}]}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.decrypters[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudkms.cryptoKeyDecrypter"},"sensitive_values":{"condition":[],"members":[]}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.encrypters[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudkms.cryptoKeyEncrypter"},"sensitive_values":{"condition":[],"members":[]}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"location":"us-central1","name":"prj-keyring","timeouts":null},"sensitive_values":{}}],"address":"module.seed_bootstrap.module.kms[0]"},{"resources":[{"address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage.google_project_organization_policy.project_policy_boolean[0]","mode":"managed","type":"google_project_organization_policy","name":"project_policy_boolean","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"boolean_policy":[{"enforced":false}],"constraint":"constraints/iam.disableCrossProjectServiceAccountUsage","list_policy":[],"restore_policy":[],"timeouts":null},"sensitive_values":{"boolean_policy":[{}],"list_policy":[],"restore_policy":[]}}],"address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage"}]},{"resources":[{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudkms.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudkms.admin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"sensitive_values":{"condition":[]}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"sensitive_values":{"condition":[]}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"bootstrap\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"env\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"env\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"net\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"net\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"org\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"org\"]"},{"resources":[{"address":"module.seed_project_iam_member[\"proj\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.objectAdmin"},"sensitive_values":{"condition":[]}}],"address":"module.seed_project_iam_member[\"proj\"]"},{"resources":[{"address":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","mode":"managed","type":"google_artifact_registry_repository","name":"tf-image-repo","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"cleanup_policies":[],"cleanup_policy_dry_run":null,"description":"Docker repository for Terraform runner images used by Cloud Build. Managed by Terraform.","docker_config":[],"effective_labels":{"goog-terraform-provisioned":"true"},"format":"DOCKER","kms_key_name":null,"labels":null,"location":"us-central1","maven_config":[],"mode":"STANDARD_REPOSITORY","remote_repository_config":[],"repository_id":"tf-runners","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"virtual_repository_config":[]},"sensitive_values":{"cleanup_policies":[],"docker_config":[],"effective_labels":{},"maven_config":[],"remote_repository_config":[],"terraform_labels":{},"virtual_repository_config":[],"vulnerability_scanning_config":[]}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.push_images","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"push_images","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.writer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.workflow_list","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"workflow_list","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_cloud_scheduler_job.trigger_workflow","mode":"managed","type":"google_cloud_scheduler_job","name":"trigger_workflow","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"app_engine_http_target":[],"attempt_deadline":null,"description":"Trigger workflow for TF Runner builds. Managed by Terraform.","http_target":[{"body":null,"headers":null,"http_method":"POST","oauth_token":[{"scope":"https://www.googleapis.com/auth/cloud-platform"}],"oidc_token":[]}],"name":"trigger-terraform-runner-workflow","pubsub_target":[],"region":"us-central1","retry_config":[],"schedule":"0 8 * * *","time_zone":"Etc/UTC","timeouts":null},"sensitive_values":{"app_engine_http_target":[],"http_target":[{"oauth_token":[{}],"oidc_token":[]}],"pubsub_target":[],"retry_config":[]}},{"address":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","mode":"managed","type":"google_cloudbuild_trigger","name":"build_trigger","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"options":[{"disk_size_gb":null,"dynamic_substitutions":null,"env":null,"log_streaming_option":null,"logging":null,"machine_type":null,"requested_verify_option":null,"secret_env":null,"source_provenance_hash":null,"substitution_option":null,"volumes":[]}],"queue_ttl":null,"secret":[],"source":[],"step":[{"allow_exit_codes":null,"allow_failure":null,"dir":null,"entrypoint":null,"env":null,"id":null,"name":"gcr.io/cloud-builders/docker","script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null},{"allow_exit_codes":null,"allow_failure":null,"args":["version"],"dir":null,"entrypoint":null,"env":null,"id":null,"script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null}],"substitutions":null,"tags":null,"timeout":"1200s"}],"description":"Builds a Terraform runner image. Managed by Terraform.","disabled":null,"filename":null,"filter":null,"git_file_source":[],"github":[],"ignored_files":null,"include_build_logs":null,"included_files":null,"location":"us-central1","name":"tf-cloud-builder-build","pubsub_config":[],"repository_event_config":[],"source_to_build":[{"bitbucket_server_config":null,"github_enterprise_config":null,"ref":"refs/heads/main","repo_type":"CLOUD_SOURCE_REPOSITORIES","repository":null}],"substitutions":{"_TERRAFORM_FULL_VERSION":"1.5.7","_TERRAFORM_MAJOR_VERSION":"1","_TERRAFORM_MINOR_VERSION":"1.5"},"tags":null,"timeouts":null,"trigger_template":[],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"images":[],"options":[{"volumes":[]}],"secret":[],"source":[],"step":[{"args":[],"volumes":[]},{"args":[false],"volumes":[]}]}],"git_file_source":[],"github":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[{}],"substitutions":{},"trigger_template":[],"webhook_config":[]}},{"address":"module.tf_cloud_builder.google_project_iam_member.invoke_workflow_scheduler","mode":"managed","type":"google_project_iam_member","name":"invoke_workflow_scheduler","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/workflows.invoker"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_project_iam_member.logs_writer","mode":"managed","type":"google_project_iam_member","name":"logs_writer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_project_iam_member.trigger_builds","mode":"managed","type":"google_project_iam_member","name":"trigger_builds","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_service_account.cb_sa[0]","mode":"managed","type":"google_service_account","name":"cb_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"tf-cb-builder-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for Terraform builder build trigger. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"module.tf_cloud_builder.google_service_account.workflow_sa[0]","mode":"managed","type":"google_service_account","name":"workflow_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"terraform-runner-workflow-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for TF Builder Workflow. Managed by Terraform.","timeouts":null},"sensitive_values":{}},{"address":"module.tf_cloud_builder.google_service_account_iam_member.use_cb_sa","mode":"managed","type":"google_service_account_iam_member","name":"use_cb_sa","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_storage_bucket_iam_member.member","mode":"managed","type":"google_storage_bucket_iam_member","name":"member","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_cloud_builder.google_workflows_workflow.builder","mode":"managed","type":"google_workflows_workflow","name":"builder","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"call_log_level":null,"crypto_key_name":null,"deletion_protection":true,"description":"Workflow for triggering TF Runner builds. Managed by Terraform.","effective_labels":{"goog-terraform-provisioned":"true"},"execution_history_level":null,"labels":null,"name":"terraform-runner-workflow","region":"us-central1","tags":null,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"user_env_vars":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}}],"address":"module.tf_cloud_builder","child_modules":[{"resources":[{"address":"module.tf_cloud_builder.module.bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_cloud_builder.module.bucket"}]},{"resources":[{"address":"module.tf_private_pool.google_cloudbuild_worker_pool.private_pool","mode":"managed","type":"google_cloudbuild_worker_pool","name":"private_pool","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"annotations":null,"display_name":null,"location":"us-central1","network_config":[{"peered_network_ip_range":null}],"private_service_connect":[],"timeouts":null,"worker_config":[{"disk_size_gb":100,"machine_type":"e2-medium","no_external_ip":true}]},"sensitive_values":{"effective_annotations":{},"network_config":[{}],"private_service_connect":[],"worker_config":[{}]}},{"address":"module.tf_private_pool.google_compute_address.cloud_build_nat","mode":"managed","type":"google_compute_address","name":"cloud_build_nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"address_type":"EXTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"ipv6_endpoint_type":null,"labels":null,"name":"cloud-build-nat","network":null,"network_tier":"PREMIUM","region":"us-central1","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{},"users":[]}},{"address":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","mode":"managed","type":"google_compute_global_address","name":"worker_pool_range","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"address":"192.168.0.0","address_type":"INTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"labels":null,"name":"ga-b-cbpools-worker-pool-range","prefix_length":24,"purpose":"VPC_PEERING","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"sensitive_values":{"effective_labels":{},"terraform_labels":{}}},{"address":"module.tf_private_pool.google_compute_instance.vm-proxy","mode":"managed","type":"google_compute_instance","name":"vm-proxy","provider_name":"registry.terraform.io/hashicorp/google","schema_version":6,"values":{"advanced_machine_features":[],"allow_stopping_for_update":null,"attached_disk":[],"boot_disk":[{"auto_delete":true,"disk_encryption_key_raw":null,"disk_encryption_key_rsa":null,"disk_encryption_service_account":null,"force_attach":null,"initialize_params":[{"enable_confidential_compute":null,"image":"debian-cloud/debian-12","resource_manager_tags":null,"source_image_encryption_key":[],"source_snapshot_encryption_key":[],"storage_pool":null}],"interface":null,"mode":"READ_WRITE"}],"can_ip_forward":true,"deletion_protection":false,"description":null,"desired_status":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_display":null,"hostname":null,"instance_encryption_key":[],"key_revocation_action_type":null,"labels":null,"machine_type":"e2-medium","metadata":null,"metadata_startup_script":"sysctl -w net.ipv4.ip_forward=1 \u0026\u0026 iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE","name":"cloud-build-nat-vm","network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[],"nic_type":null,"queue_count":null,"subnetwork":"sb-b-cbpools-us-central1"}],"network_performance_config":[],"params":[],"resource_policies":null,"scratch_disk":[],"service_account":[{"scopes":["https://www.googleapis.com/auth/cloud-platform"]}],"shielded_instance_config":[],"tags":["direct-gateway-access","nat-gateway"],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"zone":"us-central1-a"},"sensitive_values":{"advanced_machine_features":[],"attached_disk":[],"boot_disk":[{"guest_os_features":[],"initialize_params":[{"labels":{},"resource_policies":[],"source_image_encryption_key":[],"source_snapshot_encryption_key":[]}]}],"confidential_instance_config":[],"effective_labels":{},"guest_accelerator":[],"instance_encryption_key":[],"network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[]}],"network_performance_config":[],"params":[],"reservation_affinity":[],"scheduling":[],"scratch_disk":[],"service_account":[{"scopes":[false]}],"shielded_instance_config":[],"tags":[false,false],"terraform_labels":{}}},{"address":"module.tf_private_pool.google_compute_network_peering_routes_config.peering_routes[0]","mode":"managed","type":"google_compute_network_peering_routes_config","name":"peering_routes","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"export_custom_routes":true,"import_custom_routes":true,"timeouts":null},"sensitive_values":{}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway","mode":"managed","type":"google_compute_route","name":"direct-to-gateway","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"0.0.0.0/1","name":"direct-to-gateway-range1","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway2","mode":"managed","type":"google_compute_route","name":"direct-to-gateway2","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"128.0.0.0/1","name":"direct-to-gateway-range2","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_route.through-nat","mode":"managed","type":"google_compute_route","name":"through-nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"0.0.0.0/1","name":"through-nat-range1","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_route.through-nat2","mode":"managed","type":"google_compute_route","name":"through-nat2","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":null,"dest_range":"128.0.0.0/1","name":"through-nat-range2","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"sensitive_values":{"as_paths":[],"params":[],"warnings":[]}},{"address":"module.tf_private_pool.google_compute_router.cb-router","mode":"managed","type":"google_compute_router","name":"cb-router","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"bgp":[],"description":null,"encrypted_interconnect_router":null,"md5_authentication_keys":[],"name":"cb-cloud-router","region":"us-central1","timeouts":null},"sensitive_values":{"bgp":[],"md5_authentication_keys":[]}},{"address":"module.tf_private_pool.google_compute_router_nat.cb-nat","mode":"managed","type":"google_compute_router_nat","name":"cb-nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"icmp_idle_timeout_sec":30,"initial_nat_ips":null,"log_config":[{"enable":true,"filter":"ALL"}],"max_ports_per_vm":null,"name":"cb-cloud-nat","nat64_subnetwork":[],"nat_ip_allocate_option":"AUTO_ONLY","region":"us-central1","router":"cb-cloud-router","rules":[],"source_subnetwork_ip_ranges_to_nat":"ALL_SUBNETWORKS_ALL_IP_RANGES","source_subnetwork_ip_ranges_to_nat64":null,"subnetwork":[],"tcp_established_idle_timeout_sec":1200,"tcp_time_wait_timeout_sec":120,"tcp_transitory_idle_timeout_sec":30,"timeouts":null,"type":"PUBLIC","udp_idle_timeout_sec":30},"sensitive_values":{"drain_nat_ips":[],"endpoint_types":[],"log_config":[{}],"nat64_subnetwork":[],"nat_ips":[],"rules":[],"subnetwork":[]}},{"address":"module.tf_private_pool.google_dns_policy.default_policy[0]","mode":"managed","type":"google_dns_policy","name":"default_policy","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"alternative_name_server_config":[],"description":"Managed by Terraform","enable_inbound_forwarding":true,"enable_logging":true,"name":"dp-b-cbpools-default-policy","networks":[{}],"timeouts":null},"sensitive_values":{"alternative_name_server_config":[],"dns64_config":[],"networks":[{}]}},{"address":"module.tf_private_pool.google_service_networking_connection.worker_pool_conn[0]","mode":"managed","type":"google_service_networking_connection","name":"worker_pool_conn","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"deletion_policy":null,"reserved_peering_ranges":["ga-b-cbpools-worker-pool-range"],"service":"servicenetworking.googleapis.com","timeouts":null,"update_on_creation_fail":null},"sensitive_values":{"reserved_peering_ranges":[false]}},{"address":"module.tf_private_pool.random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":2,"values":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"sensitive_values":{}}],"address":"module.tf_private_pool","child_modules":[{"address":"module.tf_private_pool.module.peered_network[0]","child_modules":[{"resources":[{"address":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","mode":"managed","type":"google_compute_network","name":"network","provider_name":"registry.terraform.io/hashicorp/google-beta","schema_version":0,"values":{"auto_create_subnetworks":false,"delete_default_routes_on_create":true,"description":"","enable_ula_internal_ipv6":false,"mtu":0,"name":"vpc-b-cbpools","network_firewall_policy_enforcement_order":"AFTER_CLASSIC_FIREWALL","network_profile":null,"params":[],"routing_mode":"GLOBAL","timeouts":null},"sensitive_values":{"params":[]}}],"address":"module.tf_private_pool.module.peered_network[0].module.vpc"},{"resources":[{"address":"module.tf_private_pool.module.peered_network[0].module.subnets.google_compute_subnetwork.subnetwork[\"us-central1/sb-b-cbpools-us-central1\"]","mode":"managed","type":"google_compute_subnetwork","name":"subnetwork","index":"us-central1/sb-b-cbpools-us-central1","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"description":"Peered subnet for Cloud Build private pool","ip_cidr_range":"10.3.0.0/24","ip_collection":null,"ipv6_access_type":null,"log_config":[{"aggregation_interval":"INTERVAL_5_SEC","filter_expr":"true","flow_sampling":0.5,"metadata":"INCLUDE_ALL_METADATA","metadata_fields":null}],"name":"sb-b-cbpools-us-central1","network":"vpc-b-cbpools","params":[],"private_ip_google_access":true,"region":"us-central1","reserved_internal_range":null,"role":null,"send_secondary_ip_range_if_empty":null,"timeouts":null},"sensitive_values":{"log_config":[{}],"params":[],"secondary_ip_range":[]}}],"address":"module.tf_private_pool.module.peered_network[0].module.subnets"}]},{"resources":[{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-icmp\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-icmp","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":[],"protocol":"icmp"}],"deny":[],"description":"Allow ICMP from anywhere","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-icmp","params":[],"priority":65534,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"sensitive_values":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-pool-to-nat\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-pool-to-nat","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow all from worker pool to NAT gateway","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-pool-to-nat","params":[],"priority":1000,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":["nat-gateway"],"timeouts":null},"sensitive_values":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false],"target_tags":[false]}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-ssh-ingress\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-ssh-ingress","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":["22"],"protocol":"tcp"}],"deny":[],"description":"Allow SSH from anywhere (0.0.0.0/1)","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-ssh-ingress","params":[],"priority":1000,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"sensitive_values":{"allow":[{"ports":[false]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"fw-b-cbpools-100-i-a-all-all-all-service-networking\"]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"fw-b-cbpools-100-i-a-all-all-all-service-networking","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow ingress from the IPs configured for service networking","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"fw-b-cbpools-100-i-a-all-all-all-service-networking","params":[],"priority":100,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"sensitive_values":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}],"address":"module.tf_private_pool.module.firewall_rules[0]"}]},{"resources":[{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_editor","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_editor","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/cloudbuild.builds.editor"},"sensitive_values":{"condition":[]}},{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_viewer","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_viewer","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_source.google_project_iam_member.org_admins_source_repo_admin[0]","mode":"managed","type":"google_project_iam_member","name":"org_admins_source_repo_admin","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/source.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-bootstrap","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-bootstrap","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-environments\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-environments","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-environments","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-networks\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-networks","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-networks","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-org\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-org","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-org","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-policies\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-policies","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-policies","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-projects\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-projects","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"gcp-projects","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"tf-cloudbuilder\"]","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"tf-cloudbuilder","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"create_ignore_already_exists":null,"name":"tf-cloudbuilder","pubsub_configs":[],"timeouts":null},"sensitive_values":{"pubsub_configs":[]}},{"address":"module.tf_source.google_storage_bucket_iam_member.cloudbuild_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"cloudbuild_iam","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_source","child_modules":[{"address":"module.tf_source.module.cloudbuild_project","child_modules":[{"resources":[{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","schema_version":1,"values":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"tags":null,"terraform_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"sensitive_values":{"effective_labels":{},"labels":{},"terraform_labels":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"sensitive_values":{"service_accounts":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","mode":"managed","type":"google_service_account","name":"default_service_account","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"account_id":"project-service-account","create_ignore_already_exists":true,"description":null,"disabled":false,"timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","schema_version":0,"values":{"byte_length":2,"keepers":null,"prefix":null},"sensitive_values":{}}],"address":"module.tf_source.module.cloudbuild_project.module.project-factory","child_modules":[{"resources":[{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"artifactregistry.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"artifactregistry.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"artifactregistry.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudscheduler.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudscheduler.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudscheduler.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"dns.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"dns.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"dns.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"sourcerepo.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"sourcerepo.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"sourcerepo.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"workflows.googleapis.com\"]","mode":"managed","type":"google_project_service","name":"project_services","index":"workflows.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"workflows.googleapis.com","timeouts":null},"sensitive_values":{}}],"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services"}]}]},{"resources":[{"address":"module.tf_source.module.cloudbuild_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_source.module.cloudbuild_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"bootstrap\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"bootstrap\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket"},{"resources":[{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"env\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"env\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"env\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"env\"].module.log_bucket"},{"resources":[{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"env\"].module.artifacts_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"net\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"net\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"net\"].module.artifacts_bucket"},{"resources":[{"address":"module.tf_workspace[\"net\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"net\"].module.log_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"org\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"org\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"org\"].module.artifacts_bucket"},{"resources":[{"address":"module.tf_workspace[\"org\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"org\"].module.log_bucket"}]},{"resources":[{"address":"module.tf_workspace[\"proj\"].data.google_project.cloudbuild_project[0]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"sensitive_values":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"apply\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"plan\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","schema_version":2,"values":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"sensitive_values":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/logging.logWriter"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.pool_user[0]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountUser"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_sourcerepo_repository_iam_member.member[0]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/viewer"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"condition":[],"role":"roles/storage.admin"},"sensitive_values":{"condition":[]}}],"address":"module.tf_workspace[\"proj\"]","child_modules":[{"resources":[{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket"},{"resources":[{"address":"module.tf_workspace[\"proj\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","schema_version":0,"values":{"user_project":null},"sensitive_values":{}},{"address":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","schema_version":3,"values":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"sensitive_values":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}],"address":"module.tf_workspace[\"proj\"].module.log_bucket"}]}]}},"resource_changes":[{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"data.google_project.seed_project","mode":"data","type":"google_project","name":"seed_project","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"bootstrap\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"env\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"net\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"org\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader[\"proj\"]","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_account_sink","mode":"managed","type":"google_billing_account_iam_member","name":"billing_account_sink","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/logging.configWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.billing_admin_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"bootstrap\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"env\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"net\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"org\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_billing_account_iam_member.tf_billing_user[\"proj\"]","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"billing_account_id":"01AAD1-616217-97513A","condition":[],"role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_folder.bootstrap","mode":"managed","type":"google_folder","name":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"deletion_protection":true,"display_name":"fldr-bootstrap","parent":"folders/49822046027","tags":null,"timeouts":null},"after_unknown":{"create_time":true,"folder_id":true,"id":true,"lifecycle_state":true,"name":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_project_service_identity.workflows_identity","mode":"managed","type":"google_project_service_identity","name":"workflows_identity","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"service":"workflows.googleapis.com","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"bootstrap\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-bootstrap","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Bootstrap SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"env\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-env","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Environment SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"net\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-net","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Network SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"org\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-org","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Organization SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_service_account.terraform-env-sa[\"proj\"]","mode":"managed","type":"google_service_account","name":"terraform-env-sa","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"sa-terraform-proj","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"Foundation Projects SA. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"google_sourcerepo_repository_iam_member.member[\"bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"env\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"env","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"net\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"net","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"org\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"google_sourcerepo_repository_iam_member.member[\"proj\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":"proj","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"repository":"gcp-policies","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"after_unknown":{"id":true,"result":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"time_sleep.cloud_builder","mode":"managed","type":"time_sleep","name":"cloud_builder","provider_name":"registry.terraform.io/hashicorp/time","change":{"actions":["create"],"before":null,"after":{"create_duration":"30s","destroy_duration":null,"triggers":null},"after_unknown":{"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.bootstrap_csr_repo.null_resource.run_command[0]","module_address":"module.bootstrap_csr_repo","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"create_cmd_entrypoint":"./scripts/push-to-repo.sh","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"ad3634e17109216cf99cbd7242475359"}},"after_unknown":{"id":true,"triggers":{"arguments":true,"create_cmd_body":true}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.bootstrap_csr_repo.null_resource.run_destroy_command[0]","module_address":"module.bootstrap_csr_repo","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin"}},"after_unknown":{"id":true,"triggers":{}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.bootstrap_projects_remove_editor[\"cicd\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","module_address":"module.bootstrap_projects_remove_editor[\"cicd\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"members":null,"role":"roles/editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.bootstrap_projects_remove_editor[\"seed\"].google_project_iam_binding.iam_remove[\"roles/editor\"]","module_address":"module.bootstrap_projects_remove_editor[\"seed\"]","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","index":"roles/editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"members":null,"role":"roles/editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.build_terraform_image.null_resource.module_depends_on[0]","module_address":"module.build_terraform_image","mode":"managed","type":"null_resource","name":"module_depends_on","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"value":"1"}},"after_unknown":{"id":true,"triggers":{}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.build_terraform_image.null_resource.run_command[0]","module_address":"module.build_terraform_image","mode":"managed","type":"null_resource","name":"run_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"create_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","md5":"7f22bf39aaf5ce5980111c3587bef5b5","terraform_version":"1.5.7"}},"after_unknown":{"id":true,"triggers":{"arguments":true,"create_cmd_body":true}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.build_terraform_image.null_resource.run_destroy_command[0]","module_address":"module.build_terraform_image","mode":"managed","type":"null_resource","name":"run_destroy_command","index":0,"provider_name":"registry.terraform.io/hashicorp/null","change":{"actions":["create"],"before":null,"after":{"triggers":{"destroy_cmd_body":"info","destroy_cmd_entrypoint":"gcloud","gcloud_bin_abs_path":"/google-cloud-sdk/bin","terraform_version":"1.5.7"}},"after_unknown":{"id":true,"triggers":{}},"before_sensitive":false,"after_sensitive":{"triggers":{}}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/artifactregistry.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/artifactregistry.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.builds.editor\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.builds.editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudbuild.workerPoolOwner\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudbuild.workerPoolOwner","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolOwner"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudscheduler.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudscheduler.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudscheduler.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/compute.networkAdmin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/compute.networkAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/dns.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/dns.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.workloadIdentityPoolAdmin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.workloadIdentityPoolAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.workloadIdentityPoolAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/source.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/source.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/source.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.cicd_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/workflows.admin\"]","module_address":"module.cicd_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/workflows.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/workflows.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.gcp_projects_state_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.gcp_projects_state_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","module_address":"module.gcp_projects_state_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{"default_kms_key_name":true}],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"bootstrap\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"bootstrap\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/assuredworkloads.admin\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/assuredworkloads.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/assuredworkloads.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"env\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"env\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/compute.xpnAdmin\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/compute.xpnAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"net\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"net\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/cloudasset.owner\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudasset.owner","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/cloudasset.owner"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/essentialcontacts.admin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/essentialcontacts.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/essentialcontacts.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/logging.configWriter\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/logging.configWriter","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/logging.configWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/orgpolicy.policyAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/orgpolicy.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/orgpolicy.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationViewer\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationViewer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationViewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagAdmin\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.tagUser\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.tagUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.tagUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.notificationConfigEditor\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.notificationConfigEditor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.notificationConfigEditor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/securitycenter.sourcesEditor\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/securitycenter.sourcesEditor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/securitycenter.sourcesEditor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"org\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"org\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/accesscontextmanager.policyAdmin\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/accesscontextmanager.policyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/accesscontextmanager.policyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/browser\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/browser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/browser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/cloudkms.admin\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/cloudkms.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.org_iam_member[\"proj\"].google_organization_iam_member.org_parent_iam[\"roles/serviceusage.serviceUsageConsumer\"]","module_address":"module.org_iam_member[\"proj\"]","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","index":"roles/serviceusage.serviceUsageConsumer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"org_id":"1055058813388","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"bootstrap\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"bootstrap\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"env\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"env\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityPolicyAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityPolicyAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityPolicyAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.orgSecurityResourceAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.orgSecurityResourceAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.orgSecurityResourceAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.securityAdmin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.securityAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.securityAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/dns.admin\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/dns.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/dns.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"net\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderViewer\"]","module_address":"module.parent_iam_member[\"net\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderViewer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderViewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"org\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"org\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/artifactregistry.admin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/artifactregistry.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/artifactregistry.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.networkAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.networkAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.networkAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/compute.xpnAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/compute.xpnAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/compute.xpnAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/iam.serviceAccountAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/iam.serviceAccountAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.parent_iam_member[\"proj\"].google_folder_iam_member.folder_parent_iam[\"roles/resourcemanager.folderAdmin\"]","module_address":"module.parent_iam_member[\"proj\"]","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","index":"roles/resourcemanager.folderAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.folderAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.data.google_storage_project_service_account.gcs_account","module_address":"module.seed_bootstrap","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.seed_bootstrap.google_folder_iam_binding.project_creator[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_binding","name":"project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","role":"roles/resourcemanager.projectCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"members":true},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[]}}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_service_account_user[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_member","name":"org_admin_service_account_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_folder_iam_member.org_admin_serviceusage_consumer[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_member","name":"org_admin_serviceusage_consumer","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/serviceusage.serviceUsageConsumer"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_folder_iam_member.tmp_project_creator[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_folder_iam_member","name":"tmp_project_creator","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"folder":"49822046027","member":"group:group_org_admin_duda@clsecteam.com","role":"roles/resourcemanager.projectCreator"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_organization_iam_binding.billing_creator","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_binding","name":"billing_creator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"members":["group:billing_admin_duda_foundation@clsecteam.com"],"org_id":"1055058813388","role":"roles/billing.creator"},"after_unknown":{"condition":[],"etag":true,"id":true,"members":[false]},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[false]}}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/billing.user\"]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/billing.user","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/billing.user"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_admins_group[\"roles/resourcemanager.organizationAdmin\"]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","index":"roles/resourcemanager.organizationAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","org_id":"1055058813388","role":"roles/resourcemanager.organizationAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_organization_iam_member.org_billing_admin","module_address":"module.seed_bootstrap","mode":"managed","type":"google_organization_iam_member","name":"org_billing_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:billing_admin_duda_foundation@clsecteam.com","org_id":"1055058813388","role":"roles/billing.admin"},"after_unknown":{"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.google_storage_bucket.org_terraform_state","module_address":"module.seed_bootstrap","mode":"managed","type":"google_storage_bucket","name":"org_terraform_state","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[{}],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"requester_pays":null,"retention_policy":[],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{"default_kms_key_name":true}],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"public_access_prevention":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":true,"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[{}],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.seed_bootstrap.google_storage_bucket_iam_member.orgadmins_state_iam[0]","module_address":"module.seed_bootstrap","mode":"managed","type":"google_storage_bucket_iam_member","name":"orgadmins_state_iam","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.random_id.suffix","module_address":"module.seed_bootstrap","mode":"managed","type":"random_id","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"byte_length":2,"keepers":null,"prefix":null},"after_unknown":{"b64_std":true,"b64_url":true,"dec":true,"hex":true,"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/cloudkms.admin\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/cloudkms.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudkms.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/iam.serviceAccountAdmin\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/iam.serviceAccountAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/resourcemanager.projectDeleter\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/resourcemanager.projectDeleter","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/resourcemanager.projectDeleter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"bootstrap\"].google_project_iam_member.project_parent_iam[\"roles/storage.admin\"]","module_address":"module.seed_project_iam_member[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"env\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"env\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"net\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"net\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"org\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"org\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_project_iam_member[\"proj\"].google_project_iam_member.project_parent_iam[\"roles/storage.objectAdmin\"]","module_address":"module.seed_project_iam_member[\"proj\"]","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","index":"roles/storage.objectAdmin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.objectAdmin"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_artifact_registry_repository","name":"tf-image-repo","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"cleanup_policies":[],"cleanup_policy_dry_run":null,"description":"Docker repository for Terraform runner images used by Cloud Build. Managed by Terraform.","docker_config":[],"effective_labels":{"goog-terraform-provisioned":"true"},"format":"DOCKER","kms_key_name":null,"labels":null,"location":"us-central1","maven_config":[],"mode":"STANDARD_REPOSITORY","remote_repository_config":[],"repository_id":"tf-runners","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"virtual_repository_config":[]},"after_unknown":{"cleanup_policies":[],"create_time":true,"docker_config":[],"effective_labels":{},"id":true,"maven_config":[],"name":true,"project":true,"remote_repository_config":[],"terraform_labels":{},"update_time":true,"virtual_repository_config":[],"vulnerability_scanning_config":true},"before_sensitive":false,"after_sensitive":{"cleanup_policies":[],"docker_config":[],"effective_labels":{},"maven_config":[],"remote_repository_config":[],"terraform_labels":{},"virtual_repository_config":[],"vulnerability_scanning_config":[]}}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.push_images","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"push_images","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.writer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_artifact_registry_repository_iam_member.workflow_list","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"workflow_list","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"condition":[],"location":"us-central1","role":"roles/artifactregistry.reader"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_cloud_scheduler_job.trigger_workflow","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_cloud_scheduler_job","name":"trigger_workflow","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"app_engine_http_target":[],"attempt_deadline":null,"description":"Trigger workflow for TF Runner builds. Managed by Terraform.","http_target":[{"body":null,"headers":null,"http_method":"POST","oauth_token":[{"scope":"https://www.googleapis.com/auth/cloud-platform"}],"oidc_token":[]}],"name":"trigger-terraform-runner-workflow","pubsub_target":[],"region":"us-central1","retry_config":[],"schedule":"0 8 * * *","time_zone":"Etc/UTC","timeouts":null},"after_unknown":{"app_engine_http_target":[],"http_target":[{"oauth_token":[{"service_account_email":true}],"oidc_token":[],"uri":true}],"id":true,"paused":true,"project":true,"pubsub_target":[],"retry_config":[],"state":true},"before_sensitive":false,"after_sensitive":{"app_engine_http_target":[],"http_target":[{"oauth_token":[{}],"oidc_token":[]}],"pubsub_target":[],"retry_config":[]}}},{"address":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_cloudbuild_trigger","name":"build_trigger","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"options":[{"disk_size_gb":null,"dynamic_substitutions":null,"env":null,"log_streaming_option":null,"logging":null,"machine_type":null,"requested_verify_option":null,"secret_env":null,"source_provenance_hash":null,"substitution_option":null,"volumes":[]}],"queue_ttl":null,"secret":[],"source":[],"step":[{"allow_exit_codes":null,"allow_failure":null,"dir":null,"entrypoint":null,"env":null,"id":null,"name":"gcr.io/cloud-builders/docker","script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null},{"allow_exit_codes":null,"allow_failure":null,"args":["version"],"dir":null,"entrypoint":null,"env":null,"id":null,"script":null,"secret_env":null,"timeout":null,"timing":null,"volumes":[],"wait_for":null}],"substitutions":null,"tags":null,"timeout":"1200s"}],"description":"Builds a Terraform runner image. Managed by Terraform.","disabled":null,"filename":null,"filter":null,"git_file_source":[],"github":[],"ignored_files":null,"include_build_logs":null,"included_files":null,"location":"us-central1","name":"tf-cloud-builder-build","pubsub_config":[],"repository_event_config":[],"source_to_build":[{"bitbucket_server_config":null,"github_enterprise_config":null,"ref":"refs/heads/main","repo_type":"CLOUD_SOURCE_REPOSITORIES","repository":null}],"substitutions":{"_TERRAFORM_FULL_VERSION":"1.5.7","_TERRAFORM_MAJOR_VERSION":"1","_TERRAFORM_MINOR_VERSION":"1.5"},"tags":null,"timeouts":null,"trigger_template":[],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"images":true,"logs_bucket":true,"options":[{"volumes":[],"worker_pool":true}],"secret":[],"source":[],"step":[{"args":true,"volumes":[]},{"args":[false],"name":true,"volumes":[]}]}],"create_time":true,"git_file_source":[],"github":[],"id":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[{"uri":true}],"substitutions":{},"trigger_id":true,"trigger_template":[],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[{"artifacts":[],"available_secrets":[],"images":[],"options":[{"volumes":[]}],"secret":[],"source":[],"step":[{"args":[],"volumes":[]},{"args":[false],"volumes":[]}]}],"git_file_source":[],"github":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[{}],"substitutions":{},"trigger_template":[],"webhook_config":[]}}},{"address":"module.tf_cloud_builder.google_project_iam_member.invoke_workflow_scheduler","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_project_iam_member","name":"invoke_workflow_scheduler","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/workflows.invoker"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_project_iam_member.logs_writer","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_project_iam_member","name":"logs_writer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_project_iam_member.trigger_builds","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_project_iam_member","name":"trigger_builds","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.builds.editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_service_account.cb_sa[0]","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_service_account","name":"cb_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"tf-cb-builder-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for Terraform builder build trigger. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_cloud_builder.google_service_account.workflow_sa[0]","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_service_account","name":"workflow_sa","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"terraform-runner-workflow-sa","create_ignore_already_exists":true,"description":null,"disabled":false,"display_name":"SA for TF Builder Workflow. Managed by Terraform.","timeouts":null},"after_unknown":{"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_cloud_builder.google_service_account_iam_member.use_cb_sa","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_service_account_iam_member","name":"use_cb_sa","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_storage_bucket_iam_member.member","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_storage_bucket_iam_member","name":"member","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_cloud_builder.google_workflows_workflow.builder","module_address":"module.tf_cloud_builder","mode":"managed","type":"google_workflows_workflow","name":"builder","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"call_log_level":null,"crypto_key_name":null,"deletion_protection":true,"description":"Workflow for triggering TF Runner builds. Managed by Terraform.","effective_labels":{"goog-terraform-provisioned":"true"},"execution_history_level":null,"labels":null,"name":"terraform-runner-workflow","region":"us-central1","tags":null,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"user_env_vars":null},"after_unknown":{"create_time":true,"effective_labels":{},"id":true,"name_prefix":true,"project":true,"revision_id":true,"service_account":true,"source_contents":true,"state":true,"terraform_labels":{},"update_time":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"module.tf_private_pool.google_cloudbuild_worker_pool.private_pool","module_address":"module.tf_private_pool","mode":"managed","type":"google_cloudbuild_worker_pool","name":"private_pool","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"annotations":null,"display_name":null,"location":"us-central1","network_config":[{"peered_network_ip_range":null}],"private_service_connect":[],"timeouts":null,"worker_config":[{"disk_size_gb":100,"machine_type":"e2-medium","no_external_ip":true}]},"after_unknown":{"create_time":true,"delete_time":true,"effective_annotations":true,"id":true,"name":true,"network_config":[{"peered_network":true}],"private_service_connect":[],"project":true,"state":true,"uid":true,"update_time":true,"worker_config":[{}]},"before_sensitive":false,"after_sensitive":{"effective_annotations":{},"network_config":[{}],"private_service_connect":[],"worker_config":[{}]}}},{"address":"module.tf_private_pool.google_compute_address.cloud_build_nat","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_address","name":"cloud_build_nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"address_type":"EXTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"ipv6_endpoint_type":null,"labels":null,"name":"cloud-build-nat","network":null,"network_tier":"PREMIUM","region":"us-central1","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"address":true,"creation_timestamp":true,"effective_labels":{},"id":true,"label_fingerprint":true,"prefix_length":true,"project":true,"purpose":true,"self_link":true,"subnetwork":true,"terraform_labels":{},"users":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{},"users":[]}}},{"address":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_global_address","name":"worker_pool_range","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"address":"192.168.0.0","address_type":"INTERNAL","description":null,"effective_labels":{"goog-terraform-provisioned":"true"},"ip_version":null,"labels":null,"name":"ga-b-cbpools-worker-pool-range","prefix_length":24,"purpose":"VPC_PEERING","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null},"after_unknown":{"creation_timestamp":true,"effective_labels":{},"id":true,"label_fingerprint":true,"network":true,"project":true,"self_link":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"terraform_labels":{}}}},{"address":"module.tf_private_pool.google_compute_instance.vm-proxy","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_instance","name":"vm-proxy","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"advanced_machine_features":[],"allow_stopping_for_update":null,"attached_disk":[],"boot_disk":[{"auto_delete":true,"disk_encryption_key_raw":null,"disk_encryption_key_rsa":null,"disk_encryption_service_account":null,"force_attach":null,"initialize_params":[{"enable_confidential_compute":null,"image":"debian-cloud/debian-12","resource_manager_tags":null,"source_image_encryption_key":[],"source_snapshot_encryption_key":[],"storage_pool":null}],"interface":null,"mode":"READ_WRITE"}],"can_ip_forward":true,"deletion_protection":false,"description":null,"desired_status":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_display":null,"hostname":null,"instance_encryption_key":[],"key_revocation_action_type":null,"labels":null,"machine_type":"e2-medium","metadata":null,"metadata_startup_script":"sysctl -w net.ipv4.ip_forward=1 \u0026\u0026 iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE","name":"cloud-build-nat-vm","network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[],"nic_type":null,"queue_count":null,"subnetwork":"sb-b-cbpools-us-central1"}],"network_performance_config":[],"params":[],"resource_policies":null,"scratch_disk":[],"service_account":[{"scopes":["https://www.googleapis.com/auth/cloud-platform"]}],"shielded_instance_config":[],"tags":["direct-gateway-access","nat-gateway"],"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"zone":"us-central1-a"},"after_unknown":{"advanced_machine_features":[],"attached_disk":[],"boot_disk":[{"device_name":true,"disk_encryption_key_sha256":true,"guest_os_features":true,"initialize_params":[{"architecture":true,"labels":true,"provisioned_iops":true,"provisioned_throughput":true,"resource_policies":true,"size":true,"snapshot":true,"source_image_encryption_key":[],"source_snapshot_encryption_key":[],"type":true}],"kms_key_self_link":true,"source":true}],"confidential_instance_config":true,"cpu_platform":true,"creation_timestamp":true,"current_status":true,"effective_labels":{},"guest_accelerator":true,"id":true,"instance_encryption_key":[],"instance_id":true,"label_fingerprint":true,"metadata_fingerprint":true,"min_cpu_platform":true,"network_interface":[{"access_config":[],"alias_ip_range":[],"internal_ipv6_prefix_length":true,"ipv6_access_config":[],"ipv6_access_type":true,"ipv6_address":true,"name":true,"network":true,"network_attachment":true,"network_ip":true,"stack_type":true,"subnetwork_project":true}],"network_performance_config":[],"params":[],"project":true,"reservation_affinity":true,"scheduling":true,"scratch_disk":[],"self_link":true,"service_account":[{"email":true,"scopes":[false]}],"shielded_instance_config":[],"tags":[false,false],"tags_fingerprint":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"advanced_machine_features":[],"attached_disk":[],"boot_disk":[{"disk_encryption_key_raw":true,"disk_encryption_key_rsa":true,"guest_os_features":[],"initialize_params":[{"labels":{},"resource_policies":[],"source_image_encryption_key":[],"source_snapshot_encryption_key":[]}]}],"confidential_instance_config":[],"effective_labels":{},"guest_accelerator":[],"instance_encryption_key":[],"network_interface":[{"access_config":[],"alias_ip_range":[],"ipv6_access_config":[]}],"network_performance_config":[],"params":[],"reservation_affinity":[],"scheduling":[],"scratch_disk":[],"service_account":[{"scopes":[false]}],"shielded_instance_config":[],"tags":[false,false],"terraform_labels":{}}}},{"address":"module.tf_private_pool.google_compute_network_peering_routes_config.peering_routes[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_network_peering_routes_config","name":"peering_routes","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"export_custom_routes":true,"import_custom_routes":true,"timeouts":null},"after_unknown":{"export_subnet_routes_with_public_ip":true,"id":true,"import_subnet_routes_with_public_ip":true,"network":true,"peering":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"direct-to-gateway","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"0.0.0.0/1","name":"direct-to-gateway-range1","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"tags":[false],"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_route.direct-to-gateway2","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"direct-to-gateway2","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"128.0.0.0/1","name":"direct-to-gateway-range2","next_hop_gateway":"default-internet-gateway","next_hop_ilb":null,"next_hop_instance":null,"next_hop_vpn_tunnel":null,"params":[],"priority":5,"tags":["direct-gateway-access"],"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"tags":[false],"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"tags":[false],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_route.through-nat","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"through-nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"0.0.0.0/1","name":"through-nat-range1","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_route.through-nat2","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_route","name":"through-nat2","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":null,"dest_range":"128.0.0.0/1","name":"through-nat-range2","next_hop_gateway":null,"next_hop_ilb":null,"next_hop_vpn_tunnel":null,"params":[],"priority":10,"tags":null,"timeouts":null},"after_unknown":{"as_paths":true,"creation_timestamp":true,"id":true,"network":true,"next_hop_hub":true,"next_hop_instance":true,"next_hop_instance_zone":true,"next_hop_inter_region_cost":true,"next_hop_ip":true,"next_hop_med":true,"next_hop_network":true,"next_hop_origin":true,"next_hop_peering":true,"params":[],"project":true,"route_status":true,"route_type":true,"self_link":true,"warnings":true},"before_sensitive":false,"after_sensitive":{"as_paths":[],"params":[],"warnings":[]}}},{"address":"module.tf_private_pool.google_compute_router.cb-router","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_router","name":"cb-router","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bgp":[],"description":null,"encrypted_interconnect_router":null,"md5_authentication_keys":[],"name":"cb-cloud-router","region":"us-central1","timeouts":null},"after_unknown":{"bgp":[],"creation_timestamp":true,"id":true,"md5_authentication_keys":[],"network":true,"project":true,"self_link":true},"before_sensitive":false,"after_sensitive":{"bgp":[],"md5_authentication_keys":[]}}},{"address":"module.tf_private_pool.google_compute_router_nat.cb-nat","module_address":"module.tf_private_pool","mode":"managed","type":"google_compute_router_nat","name":"cb-nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"icmp_idle_timeout_sec":30,"initial_nat_ips":null,"log_config":[{"enable":true,"filter":"ALL"}],"max_ports_per_vm":null,"name":"cb-cloud-nat","nat64_subnetwork":[],"nat_ip_allocate_option":"AUTO_ONLY","region":"us-central1","router":"cb-cloud-router","rules":[],"source_subnetwork_ip_ranges_to_nat":"ALL_SUBNETWORKS_ALL_IP_RANGES","source_subnetwork_ip_ranges_to_nat64":null,"subnetwork":[],"tcp_established_idle_timeout_sec":1200,"tcp_time_wait_timeout_sec":120,"tcp_transitory_idle_timeout_sec":30,"timeouts":null,"type":"PUBLIC","udp_idle_timeout_sec":30},"after_unknown":{"auto_network_tier":true,"drain_nat_ips":true,"enable_dynamic_port_allocation":true,"enable_endpoint_independent_mapping":true,"endpoint_types":true,"id":true,"log_config":[{}],"min_ports_per_vm":true,"nat64_subnetwork":[],"nat_ips":true,"project":true,"rules":[],"subnetwork":[]},"before_sensitive":false,"after_sensitive":{"drain_nat_ips":[],"endpoint_types":[],"log_config":[{}],"nat64_subnetwork":[],"nat_ips":[],"rules":[],"subnetwork":[]}}},{"address":"module.tf_private_pool.google_dns_policy.default_policy[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_dns_policy","name":"default_policy","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"alternative_name_server_config":[],"description":"Managed by Terraform","enable_inbound_forwarding":true,"enable_logging":true,"name":"dp-b-cbpools-default-policy","networks":[{}],"timeouts":null},"after_unknown":{"alternative_name_server_config":[],"dns64_config":true,"id":true,"networks":[{"network_url":true}],"project":true},"before_sensitive":false,"after_sensitive":{"alternative_name_server_config":[],"dns64_config":[],"networks":[{}]}}},{"address":"module.tf_private_pool.google_service_networking_connection.worker_pool_conn[0]","module_address":"module.tf_private_pool","mode":"managed","type":"google_service_networking_connection","name":"worker_pool_conn","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"deletion_policy":null,"reserved_peering_ranges":["ga-b-cbpools-worker-pool-range"],"service":"servicenetworking.googleapis.com","timeouts":null,"update_on_creation_fail":null},"after_unknown":{"id":true,"network":true,"peering":true,"reserved_peering_ranges":[false]},"before_sensitive":false,"after_sensitive":{"reserved_peering_ranges":[false]}}},{"address":"module.tf_private_pool.random_string.suffix","module_address":"module.tf_private_pool","mode":"managed","type":"random_string","name":"suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"keepers":null,"length":4,"lower":true,"min_lower":0,"min_numeric":0,"min_special":0,"min_upper":0,"number":true,"numeric":true,"override_special":null,"special":false,"upper":false},"after_unknown":{"id":true,"result":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_editor","module_address":"module.tf_source","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_editor","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/cloudbuild.builds.editor"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_source.google_project_iam_member.org_admins_cloudbuild_viewer","module_address":"module.tf_source","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_viewer","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_source.google_project_iam_member.org_admins_source_repo_admin[0]","module_address":"module.tf_source","mode":"managed","type":"google_project_iam_member","name":"org_admins_source_repo_admin","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"member":"group:group_org_admin_duda@clsecteam.com","role":"roles/source.admin"},"after_unknown":{"condition":[],"etag":true,"id":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-bootstrap\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-bootstrap","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-bootstrap","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-environments\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-environments","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-environments","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-networks\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-networks","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-networks","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-org\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-org","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-org","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-policies\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-policies","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-policies","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"gcp-projects\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"gcp-projects","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"gcp-projects","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_sourcerepo_repository.gcp_repo[\"tf-cloudbuilder\"]","module_address":"module.tf_source","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","index":"tf-cloudbuilder","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"create_ignore_already_exists":null,"name":"tf-cloudbuilder","pubsub_configs":[],"timeouts":null},"after_unknown":{"id":true,"project":true,"pubsub_configs":[],"size":true,"url":true},"before_sensitive":false,"after_sensitive":{"pubsub_configs":[]}}},{"address":"module.tf_source.google_storage_bucket_iam_member.cloudbuild_iam","module_address":"module.tf_source","mode":"managed","type":"google_storage_bucket_iam_member","name":"cloudbuild_iam","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"bootstrap\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"env\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"env\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"env\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"net\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"net\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"net\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"org\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"org\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"org\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].data.google_project.cloudbuild_project[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"data","type":"google_project","name":"cloudbuild_project","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{},"after_unknown":{"auto_create_network":true,"billing_account":true,"deletion_policy":true,"effective_labels":true,"folder_id":true,"id":true,"labels":true,"name":true,"number":true,"org_id":true,"project_id":true,"tags":true,"terraform_labels":true},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"tags":{},"terraform_labels":{}}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"apply\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"apply","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-apply.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":false,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"plan\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","index":"plan","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"bitbucket_server_trigger_config":[],"build":[],"disabled":null,"filename":"cloudbuild-tf-plan.yaml","filter":null,"git_file_source":[],"github":[],"ignored_files":[],"include_build_logs":null,"included_files":[],"location":"us-central1","pubsub_config":[],"repository_event_config":[],"source_to_build":[],"tags":null,"timeouts":null,"trigger_template":[{"branch_name":"^(development|nonproduction|production)$","commit_sha":null,"dir":null,"invert_regex":true,"tag_name":null}],"webhook_config":[]},"after_unknown":{"approval_config":true,"bitbucket_server_trigger_config":[],"build":[],"create_time":true,"description":true,"git_file_source":[],"github":[],"id":true,"ignored_files":[],"included_files":[],"name":true,"project":true,"pubsub_config":[],"repository_event_config":[],"service_account":true,"source_to_build":[],"substitutions":true,"trigger_id":true,"trigger_template":[{"project_id":true,"repo_name":true}],"webhook_config":[]},"before_sensitive":false,"after_sensitive":{"approval_config":[],"bitbucket_server_trigger_config":[],"build":[],"git_file_source":[],"github":[],"ignored_files":[],"included_files":[],"pubsub_config":[],"repository_event_config":[],"source_to_build":[],"substitutions":{},"trigger_template":[{}],"webhook_config":[]}}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.cb_sa_logging","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/logging.logWriter"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_project_iam_member.pool_user[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_project_iam_member","name":"pool_user","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudbuild.workerPoolUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountTokenCreator\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountTokenCreator","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_sa_self[\"roles/iam.serviceAccountUser\"]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","index":"roles/iam.serviceAccountUser","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountUser"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_service_account_iam_member.cb_service_agent_impersonate[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/iam.serviceAccountTokenCreator"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"service_account_id":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_sourcerepo_repository_iam_member.member[0]","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/viewer"},"after_unknown":{"condition":[],"etag":true,"id":true,"member":true,"project":true,"repository":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.artifacts_admin","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.log_admin","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.tf_workspace[\"proj\"].google_storage_bucket_iam_member.state_admin","module_address":"module.tf_workspace[\"proj\"]","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/storage.admin"},"after_unknown":{"bucket":true,"condition":[],"etag":true,"id":true,"member":true},"before_sensitive":false,"after_sensitive":{"condition":[]}}},{"address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage.google_project_organization_policy.project_policy_boolean[0]","module_address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage","mode":"managed","type":"google_project_organization_policy","name":"project_policy_boolean","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"boolean_policy":[{"enforced":false}],"constraint":"constraints/iam.disableCrossProjectServiceAccountUsage","list_policy":[],"restore_policy":[],"timeouts":null},"after_unknown":{"boolean_policy":[{}],"etag":true,"id":true,"list_policy":[],"project":true,"restore_policy":[],"update_time":true,"version":true},"before_sensitive":false,"after_sensitive":{"boolean_policy":[{}],"list_policy":[],"restore_policy":[]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key[0]","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_crypto_key","name":"key","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"effective_labels":{"goog-terraform-provisioned":"true"},"import_only":false,"labels":null,"name":"prj-key","purpose":"ENCRYPT_DECRYPT","rotation_period":"7776000s","skip_initial_version_creation":false,"terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"version_template":[{"algorithm":"GOOGLE_SYMMETRIC_ENCRYPTION","protection_level":"SOFTWARE"}]},"after_unknown":{"crypto_key_backend":true,"destroy_scheduled_duration":true,"effective_labels":{},"id":true,"key_ring":true,"primary":true,"terraform_labels":{},"version_template":[{}]},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"primary":[],"terraform_labels":{},"version_template":[{}]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.decrypters[0]","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudkms.cryptoKeyDecrypter"},"after_unknown":{"condition":[],"crypto_key_id":true,"etag":true,"id":true,"members":true},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key_iam_binding.encrypters[0]","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"condition":[],"role":"roles/cloudkms.cryptoKeyEncrypter"},"after_unknown":{"condition":[],"crypto_key_id":true,"etag":true,"id":true,"members":true},"before_sensitive":false,"after_sensitive":{"condition":[],"members":[]}}},{"address":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","module_address":"module.seed_bootstrap.module.kms[0]","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"location":"us-central1","name":"prj-keyring","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_cloud_builder.module.bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_cloud_builder.module.bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","module_address":"module.tf_cloud_builder.module.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-icmp\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-icmp","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":[],"protocol":"icmp"}],"deny":[],"description":"Allow ICMP from anywhere","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-icmp","params":[],"priority":65534,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"after_unknown":{"allow":[{"ports":[]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-pool-to-nat\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-pool-to-nat","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow all from worker pool to NAT gateway","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-pool-to-nat","params":[],"priority":1000,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":["nat-gateway"],"timeouts":null},"after_unknown":{"allow":[{"ports":[]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false],"target_tags":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false],"target_tags":[false]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"allow-ssh-ingress\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"allow-ssh-ingress","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":["22"],"protocol":"tcp"}],"deny":[],"description":"Allow SSH from anywhere (0.0.0.0/1)","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"allow-ssh-ingress","params":[],"priority":1000,"source_ranges":["0.0.0.0/1"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"after_unknown":{"allow":[{"ports":[false]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[false]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}},{"address":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules[\"fw-b-cbpools-100-i-a-all-all-all-service-networking\"]","module_address":"module.tf_private_pool.module.firewall_rules[0]","mode":"managed","type":"google_compute_firewall","name":"rules","index":"fw-b-cbpools-100-i-a-all-all-all-service-networking","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"allow":[{"ports":[],"protocol":"all"}],"deny":[],"description":"Allow ingress from the IPs configured for service networking","direction":"INGRESS","disabled":null,"log_config":[{"metadata":"INCLUDE_ALL_METADATA"}],"name":"fw-b-cbpools-100-i-a-all-all-all-service-networking","params":[],"priority":100,"source_ranges":["192.168.0.0/24"],"source_service_accounts":null,"source_tags":null,"target_service_accounts":null,"target_tags":null,"timeouts":null},"after_unknown":{"allow":[{"ports":[]}],"creation_timestamp":true,"deny":[],"destination_ranges":true,"enable_logging":true,"id":true,"log_config":[{}],"network":true,"params":[],"project":true,"self_link":true,"source_ranges":[false]},"before_sensitive":false,"after_sensitive":{"allow":[{"ports":[]}],"deny":[],"destination_ranges":[],"log_config":[{}],"params":[],"source_ranges":[false]}}},{"address":"module.tf_source.module.cloudbuild_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_source.module.cloudbuild_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","module_address":"module.tf_source.module.cloudbuild_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"bootstrap\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"bootstrap\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"env\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"env\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"env\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"env\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"env\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"net\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"net\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"net\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"net\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"net\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"org\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"org\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"org\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"org\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"org\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"proj\"].module.artifacts_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"proj\"].module.artifacts_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.tf_workspace[\"proj\"].module.log_bucket.data.google_storage_project_service_account.gcs_account","module_address":"module.tf_workspace[\"proj\"].module.log_bucket","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["read"],"before":null,"after":{"user_project":null},"after_unknown":{"email_address":true,"id":true,"member":true,"project":true},"before_sensitive":false,"after_sensitive":{}},"action_reason":"read_because_config_unknown"},{"address":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","module_address":"module.tf_workspace[\"proj\"].module.log_bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"autoclass":[{"enabled":false}],"cors":[],"custom_placement_config":[],"default_event_based_hold":null,"effective_labels":{"goog-terraform-provisioned":"true"},"enable_object_retention":null,"encryption":[],"force_destroy":false,"hierarchical_namespace":[],"ip_filter":[],"labels":null,"lifecycle_rule":[],"location":"US-CENTRAL1","logging":[],"public_access_prevention":"inherited","requester_pays":null,"retention_policy":[],"soft_delete_policy":[{"retention_duration_seconds":604800}],"storage_class":"STANDARD","terraform_labels":{"goog-terraform-provisioned":"true"},"timeouts":null,"uniform_bucket_level_access":true,"versioning":[{"enabled":true}]},"after_unknown":{"autoclass":[{"terminal_storage_class":true}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"id":true,"ip_filter":[],"lifecycle_rule":[],"logging":[],"name":true,"project":true,"project_number":true,"retention_policy":[],"rpo":true,"self_link":true,"soft_delete_policy":[{"effective_time":true}],"terraform_labels":{},"time_created":true,"updated":true,"url":true,"versioning":[{}],"website":true},"before_sensitive":false,"after_sensitive":{"autoclass":[{}],"cors":[],"custom_placement_config":[],"effective_labels":{},"encryption":[],"hierarchical_namespace":[],"ip_filter":[],"lifecycle_rule":[],"logging":[],"retention_policy":[],"soft_delete_policy":[{}],"terraform_labels":{},"versioning":[{}],"website":[]}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"name":"prj-b-seed","tags":null,"terraform_labels":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"after_unknown":{"effective_labels":{},"folder_id":true,"id":true,"labels":{},"number":true,"org_id":true,"project_id":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"terraform_labels":{}}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"after_unknown":{"id":true,"project":true,"service_accounts":true},"before_sensitive":false,"after_sensitive":{"service_accounts":{}}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.google_resource_manager_lien.lien[0]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"google_resource_manager_lien","name":"lien","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"origin":"project-factory","reason":"Project Factory lien","restrictions":["resourcemanager.projects.delete"],"timeouts":null},"after_unknown":{"create_time":true,"id":true,"name":true,"parent":true,"restrictions":[false]},"before_sensitive":false,"after_sensitive":{"restrictions":[false]}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.random_id.random_project_id_suffix","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"byte_length":2,"keepers":null,"prefix":null},"after_unknown":{"b64_std":true,"b64_url":true,"dec":true,"hex":true,"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_private_pool.module.peered_network[0].module.subnets.google_compute_subnetwork.subnetwork[\"us-central1/sb-b-cbpools-us-central1\"]","module_address":"module.tf_private_pool.module.peered_network[0].module.subnets","mode":"managed","type":"google_compute_subnetwork","name":"subnetwork","index":"us-central1/sb-b-cbpools-us-central1","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"description":"Peered subnet for Cloud Build private pool","ip_cidr_range":"10.3.0.0/24","ip_collection":null,"ipv6_access_type":null,"log_config":[{"aggregation_interval":"INTERVAL_5_SEC","filter_expr":"true","flow_sampling":0.5,"metadata":"INCLUDE_ALL_METADATA","metadata_fields":null}],"name":"sb-b-cbpools-us-central1","network":"vpc-b-cbpools","params":[],"private_ip_google_access":true,"region":"us-central1","reserved_internal_range":null,"role":null,"send_secondary_ip_range_if_empty":null,"timeouts":null},"after_unknown":{"creation_timestamp":true,"enable_flow_logs":true,"external_ipv6_prefix":true,"fingerprint":true,"gateway_address":true,"id":true,"internal_ipv6_prefix":true,"ipv6_cidr_range":true,"ipv6_gce_endpoint":true,"log_config":[{}],"params":[],"private_ipv6_google_access":true,"project":true,"purpose":true,"secondary_ip_range":true,"self_link":true,"stack_type":true,"state":true,"subnetwork_id":true},"before_sensitive":false,"after_sensitive":{"log_config":[{}],"params":[],"secondary_ip_range":[]}}},{"address":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","module_address":"module.tf_private_pool.module.peered_network[0].module.vpc","mode":"managed","type":"google_compute_network","name":"network","provider_name":"registry.terraform.io/hashicorp/google-beta","change":{"actions":["create"],"before":null,"after":{"auto_create_subnetworks":false,"delete_default_routes_on_create":true,"description":"","enable_ula_internal_ipv6":false,"mtu":0,"name":"vpc-b-cbpools","network_firewall_policy_enforcement_order":"AFTER_CLASSIC_FIREWALL","network_profile":null,"params":[],"routing_mode":"GLOBAL","timeouts":null},"after_unknown":{"bgp_always_compare_med":true,"bgp_best_path_selection_mode":true,"bgp_inter_region_cost":true,"gateway_ipv4":true,"id":true,"internal_ipv6_range":true,"network_id":true,"numeric_id":true,"params":[],"project":true,"self_link":true},"before_sensitive":false,"after_sensitive":{"params":[]}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"google_project","name":"main","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"auto_create_network":false,"billing_account":"01AAD1-616217-97513A","deletion_policy":"PREVENT","effective_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"tags":null,"terraform_labels":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","goog-terraform-provisioned":"true","primary_contact":"example1","secondary_contact":"example2","vpc":"none"},"timeouts":null},"after_unknown":{"effective_labels":{},"folder_id":true,"id":true,"labels":{},"name":true,"number":true,"org_id":true,"project_id":true,"terraform_labels":{}},"before_sensitive":false,"after_sensitive":{"effective_labels":{},"labels":{},"terraform_labels":{}}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project_default_service_accounts.default_service_accounts[0]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"action":"DISABLE","restore_policy":"REVERT_AND_IGNORE_FAILURE","timeouts":null},"after_unknown":{"id":true,"project":true,"service_accounts":true},"before_sensitive":false,"after_sensitive":{"service_accounts":{}}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"google_service_account","name":"default_service_account","index":0,"provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"account_id":"project-service-account","create_ignore_already_exists":true,"description":null,"disabled":false,"timeouts":null},"after_unknown":{"display_name":true,"email":true,"id":true,"member":true,"name":true,"project":true,"unique_id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.random_id.random_project_id_suffix","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_name":"registry.terraform.io/hashicorp/random","change":{"actions":["create"],"before":null,"after":{"byte_length":2,"keepers":null,"prefix":null},"after_unknown":{"b64_std":true,"b64_url":true,"dec":true,"hex":true,"id":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"accesscontextmanager.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"accesscontextmanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"accesscontextmanager.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"assuredworkloads.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"assuredworkloads.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"assuredworkloads.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudasset.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudasset.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudasset.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudkms.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudkms.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudkms.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"essentialcontacts.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"essentialcontacts.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"essentialcontacts.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"iamcredentials.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"iamcredentials.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iamcredentials.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"monitoring.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"monitoring.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"monitoring.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"pubsub.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"pubsub.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"pubsub.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"securitycenter.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"securitycenter.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"securitycenter.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"admin.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"admin.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"admin.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"appengine.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"appengine.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"appengine.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"artifactregistry.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"artifactregistry.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"artifactregistry.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"bigquery.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"bigquery.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"bigquery.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"billingbudgets.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"billingbudgets.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"billingbudgets.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbilling.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbilling.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbilling.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudbuild.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudbuild.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudbuild.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudresourcemanager.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudresourcemanager.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudresourcemanager.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"cloudscheduler.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"cloudscheduler.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"cloudscheduler.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"compute.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"compute.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"compute.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"dns.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"dns.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"dns.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"iam.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"iam.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"iam.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"logging.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"logging.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"logging.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"servicenetworking.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"servicenetworking.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"servicenetworking.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"serviceusage.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"serviceusage.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"serviceusage.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"sourcerepo.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"sourcerepo.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"sourcerepo.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"storage-api.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"storage-api.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"storage-api.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}},{"address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services[\"workflows.googleapis.com\"]","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services","mode":"managed","type":"google_project_service","name":"project_services","index":"workflows.googleapis.com","provider_name":"registry.terraform.io/hashicorp/google","change":{"actions":["create"],"before":null,"after":{"disable_dependent_services":true,"disable_on_destroy":false,"service":"workflows.googleapis.com","timeouts":null},"after_unknown":{"id":true,"project":true},"before_sensitive":false,"after_sensitive":{}}}],"output_changes":{"bootstrap_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_build_peered_network_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_build_private_worker_pool_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_build_worker_peered_ip_range":{"actions":["create"],"before":null,"after":"192.168.0.0/24","after_unknown":false,"before_sensitive":false,"after_sensitive":false},"cloud_build_worker_range_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloud_builder_artifact_repo":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloudbuild_project_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"cloudbuild_project_number":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"common_config":{"actions":["create"],"before":null,"after":{"billing_account":"01AAD1-616217-97513A","default_region":"us-central1","default_region_2":"us-west1","default_region_gcs":"US","default_region_kms":"us","folder_prefix":"fldr","org_id":"1055058813388","parent_folder":"49822046027","parent_id":"folders/49822046027","project_prefix":"prj"},"after_unknown":{"bootstrap_folder_name":true},"before_sensitive":false,"after_sensitive":false},"csr_repos":{"actions":["create"],"before":null,"after":{"gcp-bootstrap":{"name":"gcp-bootstrap"},"gcp-environments":{"name":"gcp-environments"},"gcp-networks":{"name":"gcp-networks"},"gcp-org":{"name":"gcp-org"},"gcp-policies":{"name":"gcp-policies"},"gcp-projects":{"name":"gcp-projects"},"tf-cloudbuilder":{"name":"tf-cloudbuilder"}},"after_unknown":{"gcp-bootstrap":{"id":true,"project":true,"url":true},"gcp-environments":{"id":true,"project":true,"url":true},"gcp-networks":{"id":true,"project":true,"url":true},"gcp-org":{"id":true,"project":true,"url":true},"gcp-policies":{"id":true,"project":true,"url":true},"gcp-projects":{"id":true,"project":true,"url":true},"tf-cloudbuilder":{"id":true,"project":true,"url":true}},"before_sensitive":false,"after_sensitive":false},"environment_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"gcs_bucket_cloudbuild_artifacts":{"actions":["create"],"before":null,"after":{},"after_unknown":{"bootstrap":true,"env":true,"net":true,"org":true,"proj":true},"before_sensitive":false,"after_sensitive":false},"gcs_bucket_cloudbuild_logs":{"actions":["create"],"before":null,"after":{},"after_unknown":{"bootstrap":true,"env":true,"net":true,"org":true,"proj":true},"before_sensitive":false,"after_sensitive":false},"gcs_bucket_tfstate":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"networks_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"optional_groups":{"actions":["create"],"before":null,"after":{"gcp_global_secrets_admin":"","gcp_kms_admin":"","gcp_network_viewer":"","gcp_scc_admin":"","gcp_security_reviewer":""},"after_unknown":false,"before_sensitive":false,"after_sensitive":false},"organization_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"parent_id":{"actions":["create"],"before":null,"after":"folder-49822046027","after_unknown":false,"before_sensitive":false,"after_sensitive":false},"projects_gcs_bucket_tfstate":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"projects_step_terraform_service_account_email":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"required_groups":{"actions":["create"],"before":null,"after":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"},"after_unknown":false,"before_sensitive":false,"after_sensitive":false},"seed_project_id":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false},"seed_project_number":{"actions":["create"],"before":null,"after_unknown":true,"before_sensitive":false,"after_sensitive":false}},"prior_state":{"format_version":"1.0","terraform_version":"1.5.7","values":{"outputs":{"cloud_build_worker_peered_ip_range":{"sensitive":false,"value":"192.168.0.0/24","type":"string"},"optional_groups":{"sensitive":false,"value":{"gcp_global_secrets_admin":"","gcp_kms_admin":"","gcp_network_viewer":"","gcp_scc_admin":"","gcp_security_reviewer":""},"type":["map","string"]},"parent_id":{"sensitive":false,"value":"folder-49822046027","type":"string"},"required_groups":{"sensitive":false,"value":{"audit_data_users":"audit_data_users_duda@clsecteam.com","billing_data_users":"billing_data_users_duda@clsecteam.com","group_billing_admins":"billing_admin_duda_foundation@clsecteam.com","group_org_admins":"group_org_admin_duda@clsecteam.com"},"type":["map","string"]}},"root_module":{"child_modules":[{"resources":[{"address":"module.bootstrap_csr_repo.data.external.env_override[0]","mode":"data","type":"external","name":"env_override","index":0,"provider_name":"registry.terraform.io/hashicorp/external","schema_version":0,"values":{"id":"-","program":[".terraform/modules/bootstrap_csr_repo/scripts/check_env.sh"],"query":{},"result":{"download":""},"working_dir":null},"sensitive_values":{"program":[false],"query":{},"result":{}}}],"address":"module.bootstrap_csr_repo"},{"resources":[{"address":"module.build_terraform_image.data.external.env_override[0]","mode":"data","type":"external","name":"env_override","index":0,"provider_name":"registry.terraform.io/hashicorp/external","schema_version":0,"values":{"id":"-","program":[".terraform/modules/build_terraform_image/scripts/check_env.sh"],"query":{},"result":{"download":""},"working_dir":null},"sensitive_values":{"program":[false],"query":{},"result":{}}}],"address":"module.build_terraform_image"}]}}},"configuration":{"provider_config":{"google":{"name":"google","full_name":"registry.terraform.io/hashicorp/google","version_constraint":"\u003e= 3.50.0, != 4.31.0, != 6.26.0, != 6.27.0, \u003c 7.0.0"},"google-beta":{"name":"google-beta","full_name":"registry.terraform.io/hashicorp/google-beta","version_constraint":"\u003e= 3.50.0, != 4.31.0, != 6.26.0, != 6.27.0, \u003c 7.0.0","expressions":{"billing_project":{"references":["var.groups.billing_project","var.groups"]},"user_project_override":{"constant_value":true}}},"module.bootstrap_csr_repo:external":{"name":"external","full_name":"registry.terraform.io/hashicorp/external","version_constraint":"\u003e= 2.2.2","module_address":"module.bootstrap_csr_repo"},"module.bootstrap_csr_repo:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.bootstrap_csr_repo"},"module.build_terraform_image:external":{"name":"external","full_name":"registry.terraform.io/hashicorp/external","version_constraint":"\u003e= 2.2.2","module_address":"module.build_terraform_image"},"module.build_terraform_image:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.build_terraform_image"},"module.seed_bootstrap.module.enable_cross_project_service_account_usage:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.seed_bootstrap.module.enable_cross_project_service_account_usage"},"module.seed_bootstrap.module.seed_project.module.project-factory:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory"},"module.seed_bootstrap.module.seed_project.module.project-factory:random":{"name":"random","full_name":"registry.terraform.io/hashicorp/random","version_constraint":"\u003e= 2.2.0","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory"},"module.seed_bootstrap.module.seed_project.module.project-factory:time":{"name":"time","full_name":"registry.terraform.io/hashicorp/time","version_constraint":"\u003e= 0.5.0","module_address":"module.seed_bootstrap.module.seed_project.module.project-factory"},"module.seed_bootstrap.module.seed_project:google-beta":{"name":"google-beta","full_name":"registry.terraform.io/hashicorp/google-beta","version_constraint":"\u003e= 5.41.0, \u003c 7.0.0","module_address":"module.seed_bootstrap.module.seed_project"},"module.tf_source.module.cloudbuild_project.module.project-factory:null":{"name":"null","full_name":"registry.terraform.io/hashicorp/null","version_constraint":"\u003e= 2.1.0","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory"},"module.tf_source.module.cloudbuild_project.module.project-factory:random":{"name":"random","full_name":"registry.terraform.io/hashicorp/random","version_constraint":"\u003e= 2.2.0","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory"},"module.tf_source.module.cloudbuild_project.module.project-factory:time":{"name":"time","full_name":"registry.terraform.io/hashicorp/time","version_constraint":"\u003e= 0.5.0","module_address":"module.tf_source.module.cloudbuild_project.module.project-factory"},"random":{"name":"random","full_name":"registry.terraform.io/hashicorp/random"},"time":{"name":"time","full_name":"registry.terraform.io/hashicorp/time"}},"root_module":{"outputs":{"bootstrap_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"bootstrap\"].email","google_service_account.terraform-env-sa[\"bootstrap\"]","google_service_account.terraform-env-sa"]},"description":"Bootstrap Step Terraform Account"},"cloud_build_peered_network_id":{"expression":{"references":["module.tf_private_pool.peered_network_id","module.tf_private_pool"]},"description":"The ID of the Cloud Build peered network."},"cloud_build_private_worker_pool_id":{"expression":{"references":["module.tf_private_pool.private_worker_pool_id","module.tf_private_pool"]},"description":"ID of the Cloud Build private worker pool."},"cloud_build_worker_peered_ip_range":{"expression":{"references":["module.tf_private_pool.worker_peered_ip_range","module.tf_private_pool"]},"description":"The IP range of the peered service network."},"cloud_build_worker_range_id":{"expression":{"references":["module.tf_private_pool.worker_range_id","module.tf_private_pool"]},"description":"The Cloud Build private worker IP range ID."},"cloud_builder_artifact_repo":{"expression":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source","var.default_region","module.tf_cloud_builder.artifact_repo","module.tf_cloud_builder"]},"description":"Artifact Registry (AR) Repository created to store TF Cloud Builder images."},"cloudbuild_project_id":{"expression":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"description":"Project where Cloud Build configuration and terraform container image will reside."},"cloudbuild_project_number":{"expression":{"references":["data.google_project.cloudbuild_project.number","data.google_project.cloudbuild_project"]},"description":"The cloudbuild project number."},"common_config":{"expression":{"references":["var.org_id","var.parent_folder","var.billing_account","var.default_region","var.default_region_2","var.default_region_gcs","var.default_region_kms","var.project_prefix","var.folder_prefix","local.parent","google_folder.bootstrap.name","google_folder.bootstrap"]},"description":"Common configuration data to be used in other steps."},"csr_repos":{"expression":{"references":["module.tf_source.csr_repos","module.tf_source"]},"description":"List of Cloud Source Repos created by the module, linked to Cloud Build triggers."},"environment_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"env\"].email","google_service_account.terraform-env-sa[\"env\"]","google_service_account.terraform-env-sa"]},"description":"Environment Step Terraform Account"},"gcs_bucket_cloudbuild_artifacts":{"expression":{"references":["module.tf_workspace","local.bucket_self_link_prefix"]},"description":"Bucket used to store Cloud Build artifacts in cicd project."},"gcs_bucket_cloudbuild_logs":{"expression":{"references":["module.tf_workspace","local.bucket_self_link_prefix"]},"description":"Bucket used to store Cloud Build logs in cicd project."},"gcs_bucket_tfstate":{"expression":{"references":["module.seed_bootstrap.gcs_bucket_tfstate","module.seed_bootstrap"]},"description":"Bucket used for storing terraform state for Foundations Pipelines in Seed Project."},"networks_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"net\"].email","google_service_account.terraform-env-sa[\"net\"]","google_service_account.terraform-env-sa"]},"description":"Networks Step Terraform Account"},"optional_groups":{"expression":{"references":["var.groups.create_optional_groups","var.groups","var.groups.optional_groups","var.groups","module.optional_group"]},"description":"List of Google Groups created that are optional to the Example Foundation steps."},"organization_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"org\"].email","google_service_account.terraform-env-sa[\"org\"]","google_service_account.terraform-env-sa"]},"description":"Organization Step Terraform Account"},"parent_id":{"expression":{"references":["var.parent_folder","local.parent_id","var.org_id"]},"description":"Parent ID service account."},"projects_gcs_bucket_tfstate":{"expression":{"references":["module.gcp_projects_state_bucket.bucket.name","module.gcp_projects_state_bucket.bucket","module.gcp_projects_state_bucket"]},"description":"Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project."},"projects_step_terraform_service_account_email":{"expression":{"references":["google_service_account.terraform-env-sa[\"proj\"].email","google_service_account.terraform-env-sa[\"proj\"]","google_service_account.terraform-env-sa"]},"description":"Projects Step Terraform Account"},"required_groups":{"expression":{"references":["var.groups.create_required_groups","var.groups","var.groups.required_groups","var.groups","module.required_group"]},"description":"List of Google Groups created that are required by the Example Foundation steps."},"seed_project_id":{"expression":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]},"description":"Project where service accounts and core APIs will be enabled."},"seed_project_number":{"expression":{"references":["data.google_project.seed_project.number","data.google_project.seed_project"]},"description":"The seed project number."}},"resources":[{"address":"google_artifact_registry_repository_iam_member.terraform_sa_artifact_registry_reader","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"terraform_sa_artifact_registry_reader","provider_config_key":"google","expressions":{"location":{"references":["var.default_region"]},"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"project":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"repository":{"references":["local.gar_repository"]},"role":{"constant_value":"roles/artifactregistry.reader"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]}},{"address":"google_billing_account_iam_member.billing_account_sink","mode":"managed","type":"google_billing_account_iam_member","name":"billing_account_sink","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.terraform-env-sa[\"org\"].email","google_service_account.terraform-env-sa[\"org\"]","google_service_account.terraform-env-sa"]},"role":{"constant_value":"roles/logging.configWriter"}},"schema_version":0},{"address":"google_billing_account_iam_member.billing_admin_user","mode":"managed","type":"google_billing_account_iam_member","name":"billing_admin_user","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"role":{"constant_value":"roles/billing.admin"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]},"depends_on":["google_billing_account_iam_member.tf_billing_user"]},{"address":"google_billing_account_iam_member.tf_billing_user","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"role":{"constant_value":"roles/billing.user"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]},"depends_on":["google_service_account.terraform-env-sa"]},{"address":"google_folder.bootstrap","mode":"managed","type":"google_folder","name":"bootstrap","provider_config_key":"google","expressions":{"deletion_protection":{"references":["var.folder_deletion_protection"]},"display_name":{"references":["var.folder_prefix"]},"parent":{"references":["local.parent"]}},"schema_version":0},{"address":"google_project_service_identity.workflows_identity","mode":"managed","type":"google_project_service_identity","name":"workflows_identity","provider_config_key":"google-beta","expressions":{"project":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"service":{"constant_value":"workflows.googleapis.com"}},"schema_version":0,"depends_on":["module.tf_source"]},{"address":"google_service_account.terraform-env-sa","mode":"managed","type":"google_service_account","name":"terraform-env-sa","provider_config_key":"google","expressions":{"account_id":{"references":["each.key"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["each.value"]},"project":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]}},{"address":"google_sourcerepo_repository_iam_member.member","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","provider_config_key":"google","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"project":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"repository":{"references":["module.tf_source.csr_repos[\"gcp-policies\"].name","module.tf_source.csr_repos[\"gcp-policies\"]","module.tf_source.csr_repos","module.tf_source"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0,"for_each_expression":{"references":["local.granular_sa"]}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_config_key":"random","expressions":{"length":{"constant_value":4},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2},{"address":"time_sleep.cloud_builder","mode":"managed","type":"time_sleep","name":"cloud_builder","provider_config_key":"time","expressions":{"create_duration":{"constant_value":"30s"}},"schema_version":0,"depends_on":["module.tf_cloud_builder","module.bootstrap_csr_repo"]},{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"organization":{"references":["var.org_id"]}},"schema_version":0,"count_expression":{"references":["var.groups.create_required_groups","var.groups","var.groups.create_optional_groups","var.groups"]}},{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_config_key":"google","expressions":{"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]}},"schema_version":0,"depends_on":["module.tf_source"]},{"address":"data.google_project.seed_project","mode":"data","type":"google_project","name":"seed_project","provider_config_key":"google","expressions":{"project_id":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]}},"schema_version":0,"depends_on":["module.seed_bootstrap"]}],"module_calls":{"bootstrap_csr_repo":{"source":"terraform-google-modules/gcloud/google","expressions":{"create_cmd_body":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source","module.tf_source.csr_repos","module.tf_source","local.cloudbuilder_repo","path.module"]},"create_cmd_entrypoint":{"references":["path.module"]},"upgrade":{"constant_value":false}},"module":{"outputs":{"bin_dir":{"expression":{"references":["local.gcloud_bin_path"]},"description":"The full bin path of the modules executables"},"create_cmd_bin":{"expression":{"references":["local.create_cmd_bin"]},"description":"The full bin path \u0026 command used on create"},"destroy_cmd_bin":{"expression":{"references":["local.destroy_cmd_bin"]},"description":"The full bin path \u0026 command used on destroy"},"downloaded":{"expression":{"references":["local.skip_download"]},"depends_on":["local.wait"],"description":"Whether gcloud was downloaded or not"},"wait":{"expression":{"references":["local.wait"]},"description":"An output to use when you want to depend on cmd finishing"}},"resources":[{"address":"null_resource.additional_components","mode":"managed","type":"null_resource","name":"additional_components","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.additional_components_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.additional_components_destroy","mode":"managed","type":"null_resource","name":"additional_components_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.additional_components_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.decompress","mode":"managed","type":"null_resource","name":"decompress","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.decompress_command","local.download_gcloud_command","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.download_gcloud","null_resource.download_jq"]},{"address":"null_resource.decompress_destroy","mode":"managed","type":"null_resource","name":"decompress_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_wrapper","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.decompress_wrapper"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.upgrade_destroy"]},{"address":"null_resource.download_gcloud","mode":"managed","type":"null_resource","name":"download_gcloud","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_gcloud_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_gcloud_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.download_jq","mode":"managed","type":"null_resource","name":"download_jq","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_jq_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.gcloud_auth_google_credentials","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_google_credentials_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_google_credentials_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_google_credentials_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.gcloud_auth_service_account_key_file","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_service_account_key_file_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_service_account_key_file_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_service_account_key_file_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.module_depends_on","mode":"managed","type":"null_resource","name":"module_depends_on","provider_config_key":"module.bootstrap_csr_repo:null","expressions":{"triggers":{"references":["var.module_depends_on"]}},"schema_version":0,"count_expression":{"references":["var.module_depends_on"]}},{"address":"null_resource.prepare_cache","mode":"managed","type":"null_resource","name":"prepare_cache","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.prepare_cache_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.prepare_cache_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.module_depends_on"]},{"address":"null_resource.run_command","mode":"managed","type":"null_resource","name":"run_command","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.create_cmd_entrypoint","self.triggers","self","self.triggers.create_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.run_destroy_command","mode":"managed","type":"null_resource","name":"run_destroy_command","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.destroy_cmd_entrypoint","self.triggers","self","self.triggers.destroy_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.destroy_cmd_entrypoint","var.destroy_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.upgrade","mode":"managed","type":"null_resource","name":"upgrade","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.upgrade_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.decompress"]},{"address":"null_resource.upgrade_destroy","mode":"managed","type":"null_resource","name":"upgrade_destroy","provider_config_key":"module.bootstrap_csr_repo:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.upgrade_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.additional_components_destroy","null_resource.gcloud_auth_service_account_key_file_destroy","null_resource.gcloud_auth_google_credentials_destroy"]},{"address":"random_id.cache","mode":"managed","type":"random_id","name":"cache","provider_config_key":"random","expressions":{"byte_length":{"constant_value":4}},"schema_version":0,"count_expression":{"references":["local.skip_download"]}},{"address":"data.external.env_override","mode":"data","type":"external","name":"env_override","provider_config_key":"module.bootstrap_csr_repo:external","expressions":{"program":{"references":["path.module"]},"query":{"constant_value":{}}},"schema_version":0,"count_expression":{"references":["var.enabled"]}}],"variables":{"activate_service_account":{"default":true,"description":"Set to false to skip running `gcloud auth activate-service-account`. Optional."},"additional_components":{"default":[],"description":"Additional gcloud CLI components to install. Defaults to none. Valid value are components listed in `gcloud components list`"},"create_cmd_body":{"default":"info","description":"On create, the command body you'd like to run with your entrypoint."},"create_cmd_entrypoint":{"default":"gcloud","description":"On create, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"create_cmd_triggers":{"default":{},"description":"List of any additional triggers to re-run the create command execution when either of values in the maps change. Some keys are reserved and will be overwritten if specified in this option. (eg. `md5`, `arguments`, `download_gcloud_command`, `download_jq_command`, etc. See details in [the source](https://github.com/terraform-google-modules/terraform-google-gcloud/blob/master/main.tf).)"},"destroy_cmd_body":{"default":"info","description":"On destroy, the command body you'd like to run with your entrypoint."},"destroy_cmd_entrypoint":{"default":"gcloud","description":"On destroy, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"enabled":{"default":true,"description":"Flag to optionally disable usage of this module."},"gcloud_download_url":{"default":"","description":"Custom gcloud download url. Optional."},"gcloud_sdk_version":{"default":"481.0.0","description":"The gcloud sdk version to download."},"jq_download_url":{"default":"","description":"Custom jq download url. Optional."},"jq_version":{"default":"1.6","description":"The jq version to download."},"module_depends_on":{"default":[],"description":"List of modules or resources this module depends on."},"platform":{"default":"linux","description":"Platform CLI will run on. Defaults to linux. Valid values: linux, darwin"},"service_account_key_file":{"default":"","description":"Path to service account key file to run `gcloud auth activate-service-account` with. Optional."},"skip_download":{"default":true,"description":"Whether to skip downloading gcloud (assumes gcloud is already available outside the module)"},"upgrade":{"default":true,"description":"Whether to upgrade gcloud at runtime"},"use_tf_google_credentials_env_var":{"default":false,"description":"Use `GOOGLE_CREDENTIALS` environment variable to run `gcloud auth activate-service-account` with. Optional."}}},"version_constraint":"~\u003e 3.1"},"bootstrap_projects_remove_editor":{"source":"./modules/parent-iam-remove-role","expressions":{"parent_id":{"references":["each.value"]},"parent_type":{"constant_value":"project"},"roles":{"constant_value":["roles/editor"]}},"for_each_expression":{"references":["local.bootstrap_projects"]},"module":{"resources":[{"address":"google_folder_iam_binding.iam_remove","mode":"managed","type":"google_folder_iam_binding","name":"iam_remove","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"members":{"constant_value":[]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_binding.iam_remove","mode":"managed","type":"google_organization_iam_binding","name":"iam_remove","provider_config_key":"google","expressions":{"members":{"constant_value":[]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_binding.iam_remove","mode":"managed","type":"google_project_iam_binding","name":"iam_remove","provider_config_key":"google","expressions":{"members":{"constant_value":[]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to remove all members in the parent resource."}}},"depends_on":["module.seed_project_iam_member","module.cicd_project_iam_member"]},"build_terraform_image":{"source":"terraform-google-modules/gcloud/google","expressions":{"create_cmd_body":{"references":["local.cloud_builder_trigger_id","var.default_region","module.tf_source.cloudbuild_project_id","module.tf_source"]},"create_cmd_triggers":{"references":["local.terraform_version"]},"module_depends_on":{"references":["time_sleep.cloud_builder"]},"upgrade":{"constant_value":false}},"module":{"outputs":{"bin_dir":{"expression":{"references":["local.gcloud_bin_path"]},"description":"The full bin path of the modules executables"},"create_cmd_bin":{"expression":{"references":["local.create_cmd_bin"]},"description":"The full bin path \u0026 command used on create"},"destroy_cmd_bin":{"expression":{"references":["local.destroy_cmd_bin"]},"description":"The full bin path \u0026 command used on destroy"},"downloaded":{"expression":{"references":["local.skip_download"]},"depends_on":["local.wait"],"description":"Whether gcloud was downloaded or not"},"wait":{"expression":{"references":["local.wait"]},"description":"An output to use when you want to depend on cmd finishing"}},"resources":[{"address":"null_resource.additional_components","mode":"managed","type":"null_resource","name":"additional_components","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.additional_components_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.additional_components_destroy","mode":"managed","type":"null_resource","name":"additional_components_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.additional_components_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.additional_components_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.additional_components"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.decompress","mode":"managed","type":"null_resource","name":"decompress","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.decompress_command","local.download_gcloud_command","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.download_gcloud","null_resource.download_jq"]},{"address":"null_resource.decompress_destroy","mode":"managed","type":"null_resource","name":"decompress_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.decompress_wrapper","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.decompress_wrapper"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.upgrade_destroy"]},{"address":"null_resource.download_gcloud","mode":"managed","type":"null_resource","name":"download_gcloud","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_gcloud_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_gcloud_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.download_jq","mode":"managed","type":"null_resource","name":"download_jq","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.download_jq_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.download_jq_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.prepare_cache"]},{"address":"null_resource.gcloud_auth_google_credentials","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_google_credentials_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_google_credentials_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_google_credentials_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_google_credentials_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_google_credentials_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.use_tf_google_credentials_env_var"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.gcloud_auth_service_account_key_file","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_auth_service_account_key_file_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.decompress","null_resource.upgrade"]},{"address":"null_resource.gcloud_auth_service_account_key_file_destroy","mode":"managed","type":"null_resource","name":"gcloud_auth_service_account_key_file_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_auth_service_account_key_file_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.gcloud_auth_service_account_key_file_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.service_account_key_file"]},"depends_on":["null_resource.run_destroy_command"]},{"address":"null_resource.module_depends_on","mode":"managed","type":"null_resource","name":"module_depends_on","provider_config_key":"module.build_terraform_image:null","expressions":{"triggers":{"references":["var.module_depends_on"]}},"schema_version":0,"count_expression":{"references":["var.module_depends_on"]}},{"address":"null_resource.prepare_cache","mode":"managed","type":"null_resource","name":"prepare_cache","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.prepare_cache_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.prepare_cache_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","local.skip_download"]},"depends_on":["null_resource.module_depends_on"]},{"address":"null_resource.run_command","mode":"managed","type":"null_resource","name":"run_command","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.create_cmd_entrypoint","self.triggers","self","self.triggers.create_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","var.create_cmd_entrypoint","var.create_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.run_destroy_command","mode":"managed","type":"null_resource","name":"run_destroy_command","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.gcloud_bin_abs_path","self.triggers","self","self.triggers.destroy_cmd_entrypoint","self.triggers","self","self.triggers.destroy_cmd_body","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.destroy_cmd_entrypoint","var.destroy_cmd_body","local.gcloud_bin_abs_path","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled"]},"depends_on":["null_resource.module_depends_on","null_resource.decompress","null_resource.additional_components","null_resource.gcloud_auth_google_credentials","null_resource.gcloud_auth_service_account_key_file"]},{"address":"null_resource.upgrade","mode":"managed","type":"null_resource","name":"upgrade","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["var.create_cmd_entrypoint","var.create_cmd_body","local.upgrade_command","var.create_cmd_triggers"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.decompress"]},{"address":"null_resource.upgrade_destroy","mode":"managed","type":"null_resource","name":"upgrade_destroy","provider_config_key":"module.build_terraform_image:null","provisioners":[{"type":"local-exec","expressions":{"command":{"references":["self.triggers.upgrade_command","self.triggers","self"]}}}],"expressions":{"triggers":{"references":["local.upgrade_command"]}},"schema_version":0,"count_expression":{"references":["var.enabled","var.upgrade","local.skip_download"]},"depends_on":["null_resource.additional_components_destroy","null_resource.gcloud_auth_service_account_key_file_destroy","null_resource.gcloud_auth_google_credentials_destroy"]},{"address":"random_id.cache","mode":"managed","type":"random_id","name":"cache","provider_config_key":"random","expressions":{"byte_length":{"constant_value":4}},"schema_version":0,"count_expression":{"references":["local.skip_download"]}},{"address":"data.external.env_override","mode":"data","type":"external","name":"env_override","provider_config_key":"module.build_terraform_image:external","expressions":{"program":{"references":["path.module"]},"query":{"constant_value":{}}},"schema_version":0,"count_expression":{"references":["var.enabled"]}}],"variables":{"activate_service_account":{"default":true,"description":"Set to false to skip running `gcloud auth activate-service-account`. Optional."},"additional_components":{"default":[],"description":"Additional gcloud CLI components to install. Defaults to none. Valid value are components listed in `gcloud components list`"},"create_cmd_body":{"default":"info","description":"On create, the command body you'd like to run with your entrypoint."},"create_cmd_entrypoint":{"default":"gcloud","description":"On create, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"create_cmd_triggers":{"default":{},"description":"List of any additional triggers to re-run the create command execution when either of values in the maps change. Some keys are reserved and will be overwritten if specified in this option. (eg. `md5`, `arguments`, `download_gcloud_command`, `download_jq_command`, etc. See details in [the source](https://github.com/terraform-google-modules/terraform-google-gcloud/blob/master/main.tf).)"},"destroy_cmd_body":{"default":"info","description":"On destroy, the command body you'd like to run with your entrypoint."},"destroy_cmd_entrypoint":{"default":"gcloud","description":"On destroy, the command entrypoint you'd like to use. Can also be set to a custom script. Module's bin directory will be prepended to path."},"enabled":{"default":true,"description":"Flag to optionally disable usage of this module."},"gcloud_download_url":{"default":"","description":"Custom gcloud download url. Optional."},"gcloud_sdk_version":{"default":"481.0.0","description":"The gcloud sdk version to download."},"jq_download_url":{"default":"","description":"Custom jq download url. Optional."},"jq_version":{"default":"1.6","description":"The jq version to download."},"module_depends_on":{"default":[],"description":"List of modules or resources this module depends on."},"platform":{"default":"linux","description":"Platform CLI will run on. Defaults to linux. Valid values: linux, darwin"},"service_account_key_file":{"default":"","description":"Path to service account key file to run `gcloud auth activate-service-account` with. Optional."},"skip_download":{"default":true,"description":"Whether to skip downloading gcloud (assumes gcloud is already available outside the module)"},"upgrade":{"default":true,"description":"Whether to upgrade gcloud at runtime"},"use_tf_google_credentials_env_var":{"default":false,"description":"Use `GOOGLE_CREDENTIALS` environment variable to run `gcloud auth activate-service-account` with. Optional."}}},"version_constraint":"~\u003e 3.1"},"cicd_project_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["local.cicd_project_id"]},"parent_type":{"constant_value":"project"},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_cicd_project"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"gcp_projects_state_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"encryption":{"references":["local.state_bucket_kms_key"]},"force_destroy":{"references":["var.bucket_force_destroy"]},"location":{"references":["var.default_region"]},"name":{"references":["var.bucket_prefix","module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]},"project_id":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0","depends_on":["module.seed_bootstrap.gcs_bucket_tfstate"]},"optional_group":{"source":"terraform-google-modules/group/google","expressions":{"customer_id":{"references":["data.google_organization.org[0].directory_customer_id","data.google_organization.org[0]","data.google_organization.org"]},"description":{"references":["each.key"]},"display_name":{"references":["each.key"]},"id":{"references":["each.value"]},"initial_group_config":{"references":["var.initial_group_config"]}},"for_each_expression":{"references":["local.optional_groups_to_create"]},"module":{"outputs":{"id":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"ID of the group. For Google-managed entities, the ID is the email address the group"},"name":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"Name of the group with the domain removed. For Google-managed entities, the ID is the email address the group"},"resource_name":{"expression":{"references":["google_cloud_identity_group.group.name","google_cloud_identity_group.group"]},"description":"Resource name of the group in the format: groups/{group_id}, where group_id is the unique ID assigned to the group."}},"resources":[{"address":"google_cloud_identity_group.group","mode":"managed","type":"google_cloud_identity_group","name":"group","provider_config_key":"google-beta","expressions":{"description":{"references":["var.description"]},"display_name":{"references":["var.display_name"]},"group_key":[{"id":{"references":["var.id"]}}],"initial_group_config":{"references":["var.initial_group_config"]},"labels":{"references":["var.types","local.label_keys"]},"parent":{"references":["local.customer_id"]}},"schema_version":0},{"address":"google_cloud_identity_group_membership.managers","mode":"managed","type":"google_cloud_identity_group_membership","name":"managers","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}},{"name":{"constant_value":"MANAGER"}}]},"schema_version":0,"for_each_expression":{"references":["var.managers"]}},{"address":"google_cloud_identity_group_membership.members","mode":"managed","type":"google_cloud_identity_group_membership","name":"members","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.members"]}},{"address":"google_cloud_identity_group_membership.owners","mode":"managed","type":"google_cloud_identity_group_membership","name":"owners","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"OWNER"}},{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.owners"]}},{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"domain":{"references":["var.domain"]}},"schema_version":0,"count_expression":{"references":["var.domain"]}}],"variables":{"customer_id":{"default":"","description":"Customer ID of the organization to create the group in. One of domain or customer_id must be specified"},"description":{"default":"","description":"Description of the group"},"display_name":{"default":"","description":"Display name of the group"},"domain":{"default":"","description":"Domain of the organization to create the group in. One of domain or customer_id must be specified"},"id":{"description":"ID of the group. For Google-managed entities, the ID must be the email address the group"},"initial_group_config":{"default":"EMPTY","description":"The initial configuration options for creating a Group. See the API reference for possible values. Possible values are INITIAL_GROUP_CONFIG_UNSPECIFIED, WITH_INITIAL_OWNER, and EMPTY."},"managers":{"default":[],"description":"Managers of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"members":{"default":[],"description":"Members of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"owners":{"default":[],"description":"Owners of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"types":{"default":["default"],"description":"The type of the group to be created. More info: https://cloud.google.com/identity/docs/groups#group_properties"}}},"version_constraint":"~\u003e 0.7"},"org_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["var.org_id"]},"parent_type":{"constant_value":"organization"},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_org_level_roles"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"parent_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["local.parent_id"]},"parent_type":{"references":["local.parent_type"]},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_parent_level_roles"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"required_group":{"source":"terraform-google-modules/group/google","expressions":{"customer_id":{"references":["data.google_organization.org[0].directory_customer_id","data.google_organization.org[0]","data.google_organization.org"]},"description":{"references":["each.key"]},"display_name":{"references":["each.key"]},"id":{"references":["each.value"]},"initial_group_config":{"references":["var.initial_group_config"]}},"for_each_expression":{"references":["local.required_groups_to_create"]},"module":{"outputs":{"id":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"ID of the group. For Google-managed entities, the ID is the email address the group"},"name":{"expression":{"references":["google_cloud_identity_group.group.group_key[0].id","google_cloud_identity_group.group.group_key[0]","google_cloud_identity_group.group.group_key","google_cloud_identity_group.group"]},"description":"Name of the group with the domain removed. For Google-managed entities, the ID is the email address the group"},"resource_name":{"expression":{"references":["google_cloud_identity_group.group.name","google_cloud_identity_group.group"]},"description":"Resource name of the group in the format: groups/{group_id}, where group_id is the unique ID assigned to the group."}},"resources":[{"address":"google_cloud_identity_group.group","mode":"managed","type":"google_cloud_identity_group","name":"group","provider_config_key":"google-beta","expressions":{"description":{"references":["var.description"]},"display_name":{"references":["var.display_name"]},"group_key":[{"id":{"references":["var.id"]}}],"initial_group_config":{"references":["var.initial_group_config"]},"labels":{"references":["var.types","local.label_keys"]},"parent":{"references":["local.customer_id"]}},"schema_version":0},{"address":"google_cloud_identity_group_membership.managers","mode":"managed","type":"google_cloud_identity_group_membership","name":"managers","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}},{"name":{"constant_value":"MANAGER"}}]},"schema_version":0,"for_each_expression":{"references":["var.managers"]}},{"address":"google_cloud_identity_group_membership.members","mode":"managed","type":"google_cloud_identity_group_membership","name":"members","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.members"]}},{"address":"google_cloud_identity_group_membership.owners","mode":"managed","type":"google_cloud_identity_group_membership","name":"owners","provider_config_key":"google-beta","expressions":{"group":{"references":["google_cloud_identity_group.group.id","google_cloud_identity_group.group"]},"preferred_member_key":[{"id":{"references":["each.key"]}}],"roles":[{"name":{"constant_value":"OWNER"}},{"name":{"constant_value":"MEMBER"}}]},"schema_version":0,"for_each_expression":{"references":["var.owners"]}},{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"domain":{"references":["var.domain"]}},"schema_version":0,"count_expression":{"references":["var.domain"]}}],"variables":{"customer_id":{"default":"","description":"Customer ID of the organization to create the group in. One of domain or customer_id must be specified"},"description":{"default":"","description":"Description of the group"},"display_name":{"default":"","description":"Display name of the group"},"domain":{"default":"","description":"Domain of the organization to create the group in. One of domain or customer_id must be specified"},"id":{"description":"ID of the group. For Google-managed entities, the ID must be the email address the group"},"initial_group_config":{"default":"EMPTY","description":"The initial configuration options for creating a Group. See the API reference for possible values. Possible values are INITIAL_GROUP_CONFIG_UNSPECIFIED, WITH_INITIAL_OWNER, and EMPTY."},"managers":{"default":[],"description":"Managers of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"members":{"default":[],"description":"Members of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"owners":{"default":[],"description":"Owners of the group. Each entry is the ID of an entity. For Google-managed entities, the ID must be the email address of an existing group, user or service account"},"types":{"default":["default"],"description":"The type of the group to be created. More info: https://cloud.google.com/identity/docs/groups#group_properties"}}},"version_constraint":"~\u003e 0.7"},"seed_bootstrap":{"source":"terraform-google-modules/bootstrap/google","expressions":{"activate_apis":{"constant_value":["serviceusage.googleapis.com","servicenetworking.googleapis.com","cloudkms.googleapis.com","compute.googleapis.com","logging.googleapis.com","bigquery.googleapis.com","cloudresourcemanager.googleapis.com","cloudbilling.googleapis.com","cloudbuild.googleapis.com","iam.googleapis.com","admin.googleapis.com","appengine.googleapis.com","storage-api.googleapis.com","monitoring.googleapis.com","pubsub.googleapis.com","securitycenter.googleapis.com","accesscontextmanager.googleapis.com","billingbudgets.googleapis.com","essentialcontacts.googleapis.com","assuredworkloads.googleapis.com","cloudasset.googleapis.com"]},"billing_account":{"references":["var.billing_account"]},"create_terraform_sa":{"constant_value":false},"default_region":{"references":["var.default_region"]},"encrypt_gcs_bucket_tfstate":{"constant_value":true},"folder_id":{"references":["google_folder.bootstrap.id","google_folder.bootstrap"]},"force_destroy":{"references":["var.bucket_force_destroy"]},"group_billing_admins":{"references":["var.groups.required_groups.group_billing_admins","var.groups.required_groups","var.groups"]},"group_org_admins":{"references":["var.groups.required_groups.group_org_admins","var.groups.required_groups","var.groups"]},"key_rotation_period":{"constant_value":"7776000s"},"kms_prevent_destroy":{"references":["var.bucket_tfstate_kms_force_destroy"]},"org_admins_org_iam_permissions":{"references":["local.org_admins_org_iam_permissions"]},"org_id":{"references":["var.org_id"]},"org_project_creators":{"references":["local.step_terraform_sa"]},"parent_folder":{"references":["var.parent_folder","local.parent"]},"project_deletion_policy":{"references":["var.project_deletion_policy"]},"project_id":{"references":["var.project_prefix"]},"project_labels":{"constant_value":{"application_name":"seed-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"}},"project_prefix":{"references":["var.project_prefix"]},"sa_enable_impersonation":{"constant_value":true},"sa_org_iam_permissions":{"constant_value":[]},"state_bucket_name":{"references":["var.bucket_prefix","var.project_prefix"]}},"module":{"outputs":{"gcs_bucket_tfstate":{"expression":{"references":["google_storage_bucket.org_terraform_state.name","google_storage_bucket.org_terraform_state"]},"description":"Bucket used for storing terraform state for foundations pipelines in seed project."},"seed_project_id":{"expression":{"references":["module.seed_project.project_id","module.seed_project"]},"description":"Project where service accounts and core APIs will be enabled."},"terraform_sa_email":{"expression":{"references":["var.create_terraform_sa","google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"depends_on":["google_organization_iam_member.tf_sa_org_perms","google_billing_account_iam_member.tf_billing_user","google_storage_bucket_iam_member.org_terraform_state_iam","google_service_account_iam_member.org_admin_sa_user","google_service_account_iam_member.org_admin_sa_impersonate_permissions","google_organization_iam_member.org_admin_serviceusage_consumer","google_folder_iam_member.org_admin_service_account_user","google_folder_iam_member.org_admin_serviceusage_consumer","google_storage_bucket_iam_member.orgadmins_state_iam"],"description":"Email for privileged service account for Terraform."},"terraform_sa_name":{"expression":{"references":["var.create_terraform_sa","google_service_account.org_terraform[0].name","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"description":"Fully qualified name for privileged service account for Terraform."}},"resources":[{"address":"google_billing_account_iam_member.tf_billing_user","mode":"managed","type":"google_billing_account_iam_member","name":"tf_billing_user","provider_config_key":"google","expressions":{"billing_account_id":{"references":["var.billing_account"]},"member":{"references":["google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"role":{"constant_value":"roles/billing.user"}},"schema_version":0,"count_expression":{"references":["var.grant_billing_user","var.create_terraform_sa"]}},{"address":"google_folder_iam_binding.project_creator","mode":"managed","type":"google_folder_iam_binding","name":"project_creator","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"members":{"references":["local.org_project_creators"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_folder_iam_member.org_admin_service_account_user","mode":"managed","type":"google_folder_iam_member","name":"org_admin_service_account_user","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/iam.serviceAccountUser"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","local.is_organization"]}},{"address":"google_folder_iam_member.org_admin_serviceusage_consumer","mode":"managed","type":"google_folder_iam_member","name":"org_admin_serviceusage_consumer","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/serviceusage.serviceUsageConsumer"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","local.is_organization"]}},{"address":"google_folder_iam_member.tmp_project_creator","mode":"managed","type":"google_folder_iam_member","name":"tmp_project_creator","provider_config_key":"google","expressions":{"folder":{"references":["local.parent_id"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_organization_iam_binding.billing_creator","mode":"managed","type":"google_organization_iam_binding","name":"billing_creator","provider_config_key":"google","expressions":{"members":{"references":["var.group_billing_admins"]},"org_id":{"references":["var.org_id"]},"role":{"constant_value":"roles/billing.creator"}},"schema_version":0},{"address":"google_organization_iam_binding.project_creator","mode":"managed","type":"google_organization_iam_binding","name":"project_creator","provider_config_key":"google","expressions":{"members":{"references":["local.org_project_creators"]},"org_id":{"references":["local.parent_id"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_organization_iam_member.org_admin_serviceusage_consumer","mode":"managed","type":"google_organization_iam_member","name":"org_admin_serviceusage_consumer","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"org_id":{"references":["local.parent_id"]},"role":{"constant_value":"roles/serviceusage.serviceUsageConsumer"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","local.is_organization"]}},{"address":"google_organization_iam_member.org_admins_group","mode":"managed","type":"google_organization_iam_member","name":"org_admins_group","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"org_id":{"references":["var.org_id"]},"role":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.org_admins_org_iam_permissions"]}},{"address":"google_organization_iam_member.org_billing_admin","mode":"managed","type":"google_organization_iam_member","name":"org_billing_admin","provider_config_key":"google","expressions":{"member":{"references":["var.group_billing_admins"]},"org_id":{"references":["var.org_id"]},"role":{"constant_value":"roles/billing.admin"}},"schema_version":0},{"address":"google_organization_iam_member.tf_sa_org_perms","mode":"managed","type":"google_organization_iam_member","name":"tf_sa_org_perms","provider_config_key":"google","expressions":{"member":{"references":["google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"org_id":{"references":["var.org_id"]},"role":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.create_terraform_sa","var.sa_org_iam_permissions"]}},{"address":"google_organization_iam_member.tmp_project_creator","mode":"managed","type":"google_organization_iam_member","name":"tmp_project_creator","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"org_id":{"references":["local.parent_id"]},"role":{"constant_value":"roles/resourcemanager.projectCreator"}},"schema_version":0,"count_expression":{"references":["local.is_organization"]}},{"address":"google_service_account.org_terraform","mode":"managed","type":"google_service_account","name":"org_terraform","provider_config_key":"google","expressions":{"account_id":{"references":["var.tf_service_account_id"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["var.tf_service_account_name"]},"project":{"references":["module.seed_project.project_id","module.seed_project"]}},"schema_version":0,"count_expression":{"references":["var.create_terraform_sa"]}},{"address":"google_service_account_iam_member.org_admin_sa_impersonate_permissions","mode":"managed","type":"google_service_account_iam_member","name":"org_admin_sa_impersonate_permissions","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/iam.serviceAccountTokenCreator"},"service_account_id":{"references":["google_service_account.org_terraform[0].name","google_service_account.org_terraform[0]","google_service_account.org_terraform"]}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","var.create_terraform_sa"]}},{"address":"google_service_account_iam_member.org_admin_sa_user","mode":"managed","type":"google_service_account_iam_member","name":"org_admin_sa_user","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["google_service_account.org_terraform[0].name","google_service_account.org_terraform[0]","google_service_account.org_terraform"]}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation","var.create_terraform_sa"]}},{"address":"google_storage_bucket.org_terraform_state","mode":"managed","type":"google_storage_bucket","name":"org_terraform_state","provider_config_key":"google","expressions":{"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.storage_bucket_labels"]},"location":{"references":["var.default_region"]},"name":{"references":["local.state_bucket_name"]},"project":{"references":["module.seed_project.project_id","module.seed_project"]},"uniform_bucket_level_access":{"constant_value":true},"versioning":[{"enabled":{"constant_value":true}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.org_terraform_state_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"org_terraform_state_iam","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.org_terraform_state.name","google_storage_bucket.org_terraform_state"]},"member":{"references":["google_service_account.org_terraform[0].email","google_service_account.org_terraform[0]","google_service_account.org_terraform"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["var.create_terraform_sa"]}},{"address":"google_storage_bucket_iam_member.orgadmins_state_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"orgadmins_state_iam","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.org_terraform_state.name","google_storage_bucket.org_terraform_state"]},"member":{"references":["var.group_org_admins"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["var.sa_enable_impersonation"]}},{"address":"random_id.suffix","mode":"managed","type":"random_id","name":"suffix","provider_config_key":"random","expressions":{"byte_length":{"constant_value":2}},"schema_version":0},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["module.seed_project.project_id","module.seed_project"]}},"schema_version":0,"depends_on":["module.seed_project.project_id"]}],"module_calls":{"enable_cross_project_service_account_usage":{"source":"terraform-google-modules/org-policy/google","expressions":{"constraint":{"constant_value":"constraints/iam.disableCrossProjectServiceAccountUsage"},"enforce":{"constant_value":"false"},"policy_for":{"constant_value":"project"},"policy_type":{"constant_value":"boolean"},"project_id":{"references":["module.seed_project.project_id","module.seed_project"]}},"module":{"resources":[{"address":"google_folder_organization_policy.folder_policy_boolean","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_boolean","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]}},"schema_version":0,"count_expression":{"references":["local.folder","local.boolean_policy"]}},{"address":"google_folder_organization_policy.folder_policy_list_allow_all","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_allow_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"allow":[{"all":{"constant_value":true}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","local.enforce"]}},{"address":"google_folder_organization_policy.folder_policy_list_allow_values","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_allow_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"allow":[{"values":{"references":["var.allow"]}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","var.allow_list_length"]}},{"address":"google_folder_organization_policy.folder_policy_list_deny_all","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_deny_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"deny":[{"all":{"constant_value":true}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","local.enforce"]}},{"address":"google_folder_organization_policy.folder_policy_list_deny_values","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_deny_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["var.folder_id"]},"list_policy":[{"deny":[{"values":{"references":["var.deny"]}}]}]},"schema_version":0,"count_expression":{"references":["local.folder","local.list_policy","var.deny_list_length"]}},{"address":"google_folder_organization_policy.folder_policy_list_exclude_folders","mode":"managed","type":"google_folder_organization_policy","name":"folder_policy_list_exclude_folders","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"folder":{"references":["each.value"]},"restore_policy":[{"default":{"constant_value":true}}]},"schema_version":0,"for_each_expression":{"references":["local.list_policy","local.project","var.exclude_folders"]}},{"address":"google_folder_organization_policy.policy_boolean_exclude_folders","mode":"managed","type":"google_folder_organization_policy","name":"policy_boolean_exclude_folders","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"folder":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.boolean_policy","local.project","var.exclude_folders"]}},{"address":"google_organization_policy.org_policy_boolean","mode":"managed","type":"google_organization_policy","name":"org_policy_boolean","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.boolean_policy"]}},{"address":"google_organization_policy.org_policy_list_allow_all","mode":"managed","type":"google_organization_policy","name":"org_policy_list_allow_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"all":{"constant_value":true}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","local.enforce"]}},{"address":"google_organization_policy.org_policy_list_allow_values","mode":"managed","type":"google_organization_policy","name":"org_policy_list_allow_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"values":{"references":["var.allow"]}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","var.allow_list_length"]}},{"address":"google_organization_policy.org_policy_list_deny_all","mode":"managed","type":"google_organization_policy","name":"org_policy_list_deny_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"all":{"constant_value":true}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","local.enforce"]}},{"address":"google_organization_policy.org_policy_list_deny_values","mode":"managed","type":"google_organization_policy","name":"org_policy_list_deny_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"values":{"references":["var.deny"]}}]}],"org_id":{"references":["var.organization_id"]}},"schema_version":0,"count_expression":{"references":["local.organization","local.list_policy","var.deny_list_length"]}},{"address":"google_project_organization_policy.policy_boolean_exclude_projects","mode":"managed","type":"google_project_organization_policy","name":"policy_boolean_exclude_projects","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"project":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.boolean_policy","local.project","var.exclude_projects"]}},{"address":"google_project_organization_policy.project_policy_boolean","mode":"managed","type":"google_project_organization_policy","name":"project_policy_boolean","provider_config_key":"google","expressions":{"boolean_policy":[{"enforced":{"references":["var.enforce"]}}],"constraint":{"references":["var.constraint"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.boolean_policy"]}},{"address":"google_project_organization_policy.project_policy_list_allow_all","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_allow_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"all":{"constant_value":true}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","local.enforce"]}},{"address":"google_project_organization_policy.project_policy_list_allow_values","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_allow_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"allow":[{"values":{"references":["var.allow"]}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","var.allow_list_length"]}},{"address":"google_project_organization_policy.project_policy_list_deny_all","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_deny_all","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"all":{"constant_value":true}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","local.enforce"]}},{"address":"google_project_organization_policy.project_policy_list_deny_values","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_deny_values","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"list_policy":[{"deny":[{"values":{"references":["var.deny"]}}]}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.project","local.list_policy","var.deny_list_length"]}},{"address":"google_project_organization_policy.project_policy_list_exclude_projects","mode":"managed","type":"google_project_organization_policy","name":"project_policy_list_exclude_projects","provider_config_key":"google","expressions":{"constraint":{"references":["var.constraint"]},"project":{"references":["each.value"]},"restore_policy":[{"default":{"constant_value":true}}]},"schema_version":0,"for_each_expression":{"references":["local.list_policy","local.project","var.exclude_projects"]}},{"address":"null_resource.config_check","mode":"managed","type":"null_resource","name":"config_check","provider_config_key":"module.seed_bootstrap.module.enable_cross_project_service_account_usage:null","provisioners":[{"type":"local-exec","expressions":{"command":{"constant_value":"echo 'For list constraints only one of enforce, allow, and deny may be included.'; false"}}}],"schema_version":0,"count_expression":{"references":["local.invalid_config"]}}],"variables":{"allow":{"default":[""],"description":"(Only for list constraints) List of values which should be allowed"},"allow_list_length":{"default":0,"description":"The number of elements in the allow list"},"constraint":{"description":"The constraint to be applied"},"deny":{"default":[""],"description":"(Only for list constraints) List of values which should be denied"},"deny_list_length":{"default":0,"description":"The number of elements in the deny list"},"enforce":{"default":null,"description":"If boolean constraint, whether the policy is enforced at the root; if list constraint, whether to deny all (true) or allow all"},"exclude_folders":{"default":[],"description":"Set of folders to exclude from the policy"},"exclude_projects":{"default":[],"description":"Set of projects to exclude from the policy"},"folder_id":{"default":null,"description":"The folder id for putting the policy"},"organization_id":{"default":null,"description":"The organization id for putting the policy"},"policy_for":{"description":"Resource hierarchy node to apply the policy to: can be one of `organization`, `folder`, or `project`."},"policy_type":{"default":"list","description":"The constraint type to work with (either 'boolean' or 'list')"},"project_id":{"default":null,"description":"The project id for putting the policy"}}},"version_constraint":"~\u003e 6.0"},"kms":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_protection_level":{"references":["var.key_protection_level"]},"key_rotation_period":{"references":["var.key_rotation_period"]},"keyring":{"references":["var.project_prefix"]},"keys":{"references":["var.project_prefix"]},"location":{"references":["var.default_region"]},"prevent_destroy":{"references":["var.kms_prevent_destroy"]},"project_id":{"references":["module.seed_project.project_id","module.seed_project"]},"set_decrypters_for":{"references":["var.project_prefix"]},"set_encrypters_for":{"references":["var.project_prefix"]}},"count_expression":{"references":["var.encrypt_gcs_bucket_tfstate"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.2"},"seed_project":{"source":"terraform-google-modules/project-factory/google","expressions":{"activate_apis":{"references":["local.activate_apis"]},"auto_create_network":{"references":["var.project_auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"create_project_sa":{"constant_value":false},"deletion_policy":{"references":["var.project_deletion_policy"]},"disable_services_on_destroy":{"constant_value":false},"folder_id":{"references":["var.folder_id"]},"labels":{"references":["var.project_labels"]},"lien":{"constant_value":true},"name":{"references":["local.seed_project_id"]},"org_id":{"references":["local.seed_org_depends_on"]},"random_project_id":{"references":["var.random_suffix"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["module.project-factory.api_s_account","module.project-factory"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["module.project-factory.api_s_account_fmt","module.project-factory"]},"description":"API service account email formatted for terraform use"},"budget_name":{"expression":{"references":["module.budget.name","module.budget"]},"description":"The name of the budget if created"},"domain":{"expression":{"references":["module.gsuite_group.domain","module.gsuite_group"]},"description":"The organization's domain"},"enabled_api_identities":{"expression":{"references":["module.project-factory.enabled_api_identities","module.project-factory"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project-factory.enabled_apis","module.project-factory"]},"description":"Enabled APIs in the project"},"group_email":{"expression":{"references":["module.gsuite_group.email","module.gsuite_group"]},"description":"The email of the G Suite group with group_name"},"project_bucket_self_link":{"expression":{"references":["module.project-factory.project_bucket_self_link","module.project-factory"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["module.project-factory.project_bucket_url","module.project-factory"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project-factory.project_id","module.project-factory"]},"description":"ID of the project"},"project_name":{"expression":{"references":["module.project-factory.project_name","module.project-factory"]},"description":"Name of the project"},"project_number":{"expression":{"references":["module.project-factory.project_number","module.project-factory"]},"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["module.project-factory.service_account_display_name","module.project-factory"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["module.project-factory.service_account_email","module.project-factory"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["module.project-factory.service_account_id","module.project-factory"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["module.project-factory.service_account_name","module.project-factory"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["module.project-factory.service_account_unique_id","module.project-factory"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["module.project-factory.tag_bindings","module.project-factory"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["module.project-factory.usage_report_export_bucket","module.project-factory"]},"description":"GCE usage reports bucket"}},"module_calls":{"budget":{"source":"./modules/budget","expressions":{"alert_pubsub_topic":{"references":["var.budget_alert_pubsub_topic"]},"alert_spend_basis":{"references":["var.budget_alert_spend_basis"]},"alert_spent_percents":{"references":["var.budget_alert_spent_percents"]},"amount":{"references":["var.budget_amount"]},"billing_account":{"references":["var.billing_account"]},"calendar_period":{"references":["var.budget_calendar_period"]},"create_budget":{"references":["var.budget_amount"]},"custom_period_end_date":{"references":["var.budget_custom_period_end_date"]},"custom_period_start_date":{"references":["var.budget_custom_period_start_date"]},"display_name":{"references":["var.budget_display_name","var.budget_display_name"]},"labels":{"references":["var.budget_labels"]},"monitoring_notification_channels":{"references":["var.budget_monitoring_notification_channels"]},"projects":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"name":{"expression":{"references":["google_billing_budget.budget","google_billing_budget.budget[0].name","google_billing_budget.budget[0]","google_billing_budget.budget"]},"description":"Resource name of the budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}.`"}},"resources":[{"address":"google_billing_budget.budget","mode":"managed","type":"google_billing_budget","name":"budget","provider_config_key":"google","expressions":{"amount":[{"specified_amount":[{"units":{"references":["var.amount"]}}]}],"billing_account":{"references":["var.billing_account"]},"budget_filter":[{"calendar_period":{"references":["local.custom_period","var.calendar_period"]},"credit_types_treatment":{"references":["var.credit_types_treatment"]},"labels":{"references":["var.labels"]},"projects":{"references":["local.projects"]},"services":{"references":["local.services"]}}],"display_name":{"references":["local.display_name"]}},"schema_version":1,"count_expression":{"references":["var.create_budget"]}},{"address":"data.google_project.project","mode":"data","type":"google_project","name":"project","provider_config_key":"google","expressions":{"project_id":{"references":["var.projects","count.index"]}},"schema_version":0,"count_expression":{"references":["var.create_budget","var.projects"]},"depends_on":["var.projects"]}],"variables":{"alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"amount":{"description":"The amount to use as the budget"},"billing_account":{"description":"ID of the billing account to set a budget on"},"calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"create_budget":{"default":true,"description":"If the budget should be created"},"credit_types_treatment":{"default":"INCLUDE_ALL_CREDITS","description":"Specifies how credits should be treated when determining spend for threshold calculations"},"custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"projects":{"description":"The project ids to include in this budget. If empty budget will include all projects"},"services":{"default":null,"description":"A list of services ids to be included in the budget. If omitted, all services will be included in the budget. Service ids can be found at https://cloud.google.com/skus/"}}}},"essential_contacts":{"source":"./modules/essential_contacts","expressions":{"essential_contacts":{"references":["var.essential_contacts"]},"language_tag":{"references":["var.language_tag"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"essential_contacts":{"expression":{"references":["google_essential_contacts_contact.contact"]},"description":"Essential Contact resources created"},"project_id":{"expression":{"references":["var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_essential_contacts_contact.contact","mode":"managed","type":"google_essential_contacts_contact","name":"contact","provider_config_key":"google","expressions":{"email":{"references":["each.key"]},"language_tag":{"references":["var.language_tag"]},"notification_category_subscriptions":{"references":["each.value"]},"parent":{"references":["var.project_id"]}},"schema_version":0,"for_each_expression":{"references":["var.essential_contacts"]}}],"variables":{"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"language_tag":{"description":"Language code to be used for essential contacts notifiactions"},"project_id":{"description":"The GCP project you want to send Essential Contacts notifications for"}}}},"gsuite_group":{"source":"./modules/gsuite_group","expressions":{"domain":{"references":["var.domain"]},"name":{"references":["var.group_name"]},"org_id":{"references":["var.org_id"]}},"module":{"outputs":{"domain":{"expression":{"references":["local.domain"]},"description":"The domain of the group's organization."},"email":{"expression":{"references":["local.email"]},"description":"The email address of the group."},"name":{"expression":{"references":["var.name"]},"description":"The username portion of the email address of the group."}},"resources":[{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"organization":{"references":["var.org_id"]}},"schema_version":0,"count_expression":{"references":["var.domain","var.name"]}}],"variables":{"domain":{"default":"","description":"The domain name"},"name":{"default":"","description":"The name of the group."},"org_id":{"default":null,"description":"The organization ID."}}}},"project-factory":{"source":"./modules/core_project_factory","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["var.activate_apis"]},"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"bucket_force_destroy":{"references":["var.bucket_force_destroy"]},"bucket_labels":{"references":["var.bucket_labels"]},"bucket_location":{"references":["var.bucket_location"]},"bucket_name":{"references":["var.bucket_name"]},"bucket_pap":{"references":["var.bucket_pap"]},"bucket_project":{"references":["var.bucket_project"]},"bucket_ula":{"references":["var.bucket_ula"]},"bucket_versioning":{"references":["var.bucket_versioning"]},"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"create_project_sa":{"references":["var.create_project_sa"]},"default_network_tier":{"references":["var.default_network_tier"]},"default_service_account":{"references":["var.default_service_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"enable_shared_vpc_host_project":{"references":["var.enable_shared_vpc_host_project"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"folder_id":{"references":["var.folder_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"group_email":{"references":["module.gsuite_group.email","module.gsuite_group"]},"group_role":{"references":["var.group_role"]},"labels":{"references":["var.labels"]},"lien":{"references":["var.lien"]},"manage_group":{"references":["var.group_name"]},"name":{"references":["var.name"]},"org_id":{"references":["var.folder_id","var.org_id"]},"project_id":{"references":["var.project_id"]},"project_sa_name":{"references":["var.project_sa_name"]},"random_project_id":{"references":["var.random_project_id"]},"random_project_id_length":{"references":["var.random_project_id_length"]},"sa_role":{"references":["var.sa_role"]},"shared_vpc":{"references":["var.svpc_host_project_id"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]},"tag_binding_values":{"references":["var.tag_binding_values"]},"usage_bucket_name":{"references":["var.usage_bucket_name"]},"usage_bucket_prefix":{"references":["var.usage_bucket_prefix"]},"vpc_service_control_attach_dry_run":{"references":["var.vpc_service_control_attach_dry_run"]},"vpc_service_control_attach_enabled":{"references":["var.vpc_service_control_attach_enabled"]},"vpc_service_control_perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"vpc_service_control_sleep_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["local.api_s_account"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["local.api_s_account_fmt"]},"description":"API service account email formatted for terraform use"},"enabled_api_identities":{"expression":{"references":["module.project_services.enabled_api_identities","module.project_services"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project_services.enabled_apis","module.project_services"]},"description":"Enabled APIs in the project"},"project_bucket_name":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"The name of the projec's bucket"},"project_bucket_self_link":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project_services.project_id","module.project_services"]},"depends_on":["module.project_services","google_project.main","google_compute_shared_vpc_service_project.shared_vpc_attachment","google_compute_shared_vpc_host_project.shared_vpc_host"],"description":"ID of the project"},"project_name":{"expression":{"references":["google_project.main.name","google_project.main"]},"description":"Name of the project"},"project_number":{"expression":{"references":["google_project.main.number","google_project.main"]},"depends_on":["module.project_services"],"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].display_name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].account_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].unique_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["google_tags_tag_binding.bindings"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["google_project_usage_export_bucket.usage_report_export[0]","google_project_usage_export_bucket.usage_report_export"]},"description":"GCE usage reports bucket"}},"resources":[{"address":"google_access_context_manager_service_perimeter_dry_run_resource.service_perimeter_attachment_dry_run","mode":"managed","type":"google_access_context_manager_service_perimeter_dry_run_resource","name":"service_perimeter_attachment_dry_run","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_dry_run","var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_access_context_manager_service_perimeter_resource.service_perimeter_attachment","mode":"managed","type":"google_access_context_manager_service_perimeter_resource","name":"service_perimeter_attachment","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_compute_project_cloud_armor_tier.cloud_armor_tier_config","mode":"managed","type":"google_compute_project_cloud_armor_tier","name":"cloud_armor_tier_config","provider_config_key":"google","expressions":{"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.cloud_armor_tier"]}},{"address":"google_compute_project_default_network_tier.default","mode":"managed","type":"google_compute_project_default_network_tier","name":"default","provider_config_key":"google","expressions":{"network_tier":{"references":["var.default_network_tier"]},"project":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.default_network_tier"]}},{"address":"google_compute_shared_vpc_host_project.shared_vpc_host","mode":"managed","type":"google_compute_shared_vpc_host_project","name":"shared_vpc_host","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_host_project"]},"depends_on":["module.project_services"]},{"address":"google_compute_shared_vpc_service_project.shared_vpc_attachment","mode":"managed","type":"google_compute_shared_vpc_service_project","name":"shared_vpc_attachment","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"host_project":{"references":["var.shared_vpc"]},"service_project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_service_project"]},"depends_on":["time_sleep.wait_5_seconds[0]","module.project_services"]},{"address":"google_compute_subnetwork_iam_member.apis_service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"apis_service_account_role_to_vpc_subnets","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.api_s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.shared_vpc_subnets"]},"depends_on":["module.project_services"]},{"address":"google_compute_subnetwork_iam_member.group_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"group_role_to_vpc_subnets","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.manage_group","var.shared_vpc_subnets"]}},{"address":"google_compute_subnetwork_iam_member.service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_account_role_to_vpc_subnets","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.create_project_sa","var.shared_vpc_subnets"]}},{"address":"google_project.main","mode":"managed","type":"google_project","name":"main","provider_config_key":"google","expressions":{"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"folder_id":{"references":["local.project_folder_id"]},"labels":{"references":["var.labels"]},"name":{"references":["var.name"]},"org_id":{"references":["local.project_org_id"]},"project_id":{"references":["local.temp_project_id"]}},"schema_version":1},{"address":"google_project_default_service_accounts.default_service_accounts","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","provider_config_key":"google","expressions":{"action":{"references":["var.default_service_account"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"restore_policy":{"constant_value":"REVERT_AND_IGNORE_FAILURE"}},"schema_version":0,"count_expression":{"references":["var.default_service_account"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.controlling_group_vpc_membership","mode":"managed","type":"google_project_iam_member","name":"controlling_group_vpc_membership","provider_config_key":"google","expressions":{"member":{"references":["local.shared_vpc_users","count.index"]},"project":{"references":["var.shared_vpc"]},"role":{"constant_value":"roles/compute.networkUser"}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","local.shared_vpc_users_length"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.default_service_account_membership","mode":"managed","type":"google_project_iam_member","name":"default_service_account_membership","provider_config_key":"google","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.sa_role"]}},"schema_version":0,"count_expression":{"references":["var.sa_role","var.create_project_sa"]}},{"address":"google_project_iam_member.gsuite_group_role","mode":"managed","type":"google_project_iam_member","name":"gsuite_group_role","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.group_role"]}},"schema_version":0,"count_expression":{"references":["var.manage_group"]}},{"address":"google_project_service.enable_access_context_manager","mode":"managed","type":"google_project_service","name":"enable_access_context_manager","provider_config_key":"google","expressions":{"project":{"references":["google_project.main.number","google_project.main"]},"service":{"constant_value":"accesscontextmanager.googleapis.com"}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]}},{"address":"google_project_usage_export_bucket.usage_report_export","mode":"managed","type":"google_project_usage_export_bucket","name":"usage_report_export","provider_config_key":"google","expressions":{"bucket_name":{"references":["var.usage_bucket_name"]},"prefix":{"references":["var.usage_bucket_prefix","var.usage_bucket_prefix","google_project.main.project_id","google_project.main"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.usage_bucket_name"]},"depends_on":["module.project_services"]},{"address":"google_resource_manager_lien.lien","mode":"managed","type":"google_resource_manager_lien","name":"lien","provider_config_key":"google","expressions":{"origin":{"constant_value":"project-factory"},"parent":{"references":["google_project.main.number","google_project.main"]},"reason":{"constant_value":"Project Factory lien"},"restrictions":{"constant_value":["resourcemanager.projects.delete"]}},"schema_version":0,"count_expression":{"references":["var.lien"]}},{"address":"google_service_account.default_service_account","mode":"managed","type":"google_service_account","name":"default_service_account","provider_config_key":"google","expressions":{"account_id":{"references":["var.project_sa_name"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["var.name"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.create_project_sa"]}},{"address":"google_service_account_iam_member.service_account_grant_to_group","mode":"managed","type":"google_service_account_iam_member","name":"service_account_grant_to_group","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["google_project.main.project_id","google_project.main","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]}},"schema_version":0,"count_expression":{"references":["var.manage_group","var.create_project_sa"]}},{"address":"google_storage_bucket.project_bucket","mode":"managed","type":"google_storage_bucket","name":"project_bucket","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"force_destroy":{"references":["var.bucket_force_destroy"]},"labels":{"references":["var.bucket_labels"]},"location":{"references":["var.bucket_location"]},"name":{"references":["local.project_bucket_name"]},"project":{"references":["var.bucket_project","local.base_project_id","google_project.main.project_id","google_project.main","var.bucket_project"]},"public_access_prevention":{"references":["var.bucket_pap"]},"uniform_bucket_level_access":{"references":["var.bucket_ula"]},"versioning":[{"enabled":{"references":["var.bucket_versioning"]}}]},"schema_version":3,"count_expression":{"references":["local.create_bucket"]}},{"address":"google_storage_bucket_iam_member.api_s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"api_s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.api_s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket"]},"depends_on":["module.project_services"]},{"address":"google_storage_bucket_iam_member.group_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"group_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.manage_group"]}},{"address":"google_storage_bucket_iam_member.s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.create_project_sa"]}},{"address":"google_tags_tag_binding.bindings","mode":"managed","type":"google_tags_tag_binding","name":"bindings","provider_config_key":"google","expressions":{"parent":{"references":["google_project.main.number","google_project.main"]},"tag_value":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.tag_binding_values"]}},{"address":"random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_config_key":"module.seed_bootstrap.module.seed_project.module.project-factory:random","expressions":{"byte_length":{"constant_value":2}},"schema_version":0},{"address":"random_string.random_project_id_suffix","mode":"managed","type":"random_string","name":"random_project_id_suffix","provider_config_key":"module.seed_bootstrap.module.seed_project.module.project-factory:random","expressions":{"length":{"references":["var.random_project_id_length"]},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2,"count_expression":{"references":["local.use_random_string"]}},{"address":"time_sleep.wait_5_seconds","mode":"managed","type":"time_sleep","name":"wait_5_seconds","provider_config_key":"module.seed_bootstrap.module.seed_project.module.project-factory:time","expressions":{"create_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]},"depends_on":["google_access_context_manager_service_perimeter_resource.service_perimeter_attachment[0]","google_project_service.enable_access_context_manager[0]"]}],"module_calls":{"project_services":{"source":"../project_services","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["local.activate_apis"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"project_id":{"references":["google_project.main.project_id","google_project.main"]}},"module":{"outputs":{"enabled_api_identities":{"expression":{"references":["google_project_service_identity.project_service_identities"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["google_project_service.project_services"]},"description":"Enabled APIs in the project"},"project_id":{"expression":{"references":["google_project_service.project_services","var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_project_iam_member.project_service_identity_roles","mode":"managed","type":"google_project_iam_member","name":"project_service_identity_roles","provider_config_key":"google","expressions":{"member":{"references":["each.value.email","each.value"]},"project":{"references":["var.project_id"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.add_service_roles"]}},{"address":"google_project_service.project_services","mode":"managed","type":"google_project_service","name":"project_services","provider_config_key":"google","expressions":{"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_on_destroy":{"references":["var.disable_services_on_destroy"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.services"]}},{"address":"google_project_service_identity.project_service_identities","mode":"managed","type":"google_project_service_identity","name":"project_service_identities","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"project":{"references":["var.project_id"]},"service":{"references":["each.value.api","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.activate_api_identities"]}},{"address":"data.google_compute_default_service_account.default","mode":"data","type":"google_compute_default_service_account","name":"default","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.activate_compute_identity"]}}],"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":[],"description":"The list of apis to activate within the project"},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_dependent_services"},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_on_destroy"},"enable_apis":{"default":true,"description":"Whether to actually enable the APIs. If false, this module is a no-op."},"project_id":{"description":"The GCP project you want to enable APIs on"}}}}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`. Use for services supported by `gcloud beta services identity create`\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false."},"enable_shared_vpc_service_project":{"description":"If this project should be attached to a shared VPC. If true, you must set shared_vpc variable."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"group_email":{"default":"","description":"The email address of a group to control the project by being assigned group_role."},"group_role":{"default":"","description":"The role to give the controlling group (group_name) over the project."},"labels":{"default":{},"description":"Map of labels for project"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"manage_group":{"default":false,"description":"A toggle to indicate if a G Suite group should be managed."},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}}},"quotas":{"source":"./modules/quota_manager","expressions":{"consumer_quotas":{"references":["var.consumer_quotas"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"quota_overrides":{"expression":{"references":["google_service_usage_consumer_quota_override.override"]},"description":"The server-generated names of the quota override."}},"resources":[{"address":"google_service_usage_consumer_quota_override.override","mode":"managed","type":"google_service_usage_consumer_quota_override","name":"override","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"dimensions":{"references":["each.value.dimensions","each.value"]},"force":{"constant_value":true},"limit":{"references":["each.value.limit","each.value"]},"metric":{"references":["each.value.metric","each.value"]},"override_value":{"references":["each.value.value","each.value"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value.service","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.consumer_quotas"]}}],"variables":{"consumer_quotas":{"description":"The quotas configuration you want to override for the project."},"project_id":{"description":"The GCP project where you want to manage the consumer quotas"}}}},"shared_vpc_access":{"source":"./modules/shared_vpc_access","expressions":{"active_apis":{"references":["var.activate_apis","var.activate_api_identities"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"grant_services_security_admin_role":{"references":["var.grant_services_security_admin_role"]},"host_project_id":{"references":["var.svpc_host_project_id"]},"lookup_project_numbers":{"constant_value":false},"service_project_id":{"references":["module.project-factory.project_id","module.project-factory"]},"service_project_number":{"references":["module.project-factory.project_number","module.project-factory"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]}},"module":{"outputs":{"active_api_service_accounts":{"expression":{"references":["local.active_apis"]},"description":"List of active API service accounts in the service project."},"project_id":{"expression":{"references":["var.service_project_id"]},"depends_on":["google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","google_project_iam_member.gke_host_agent","google_project_iam_member.service_shared_vpc_user"],"description":"Service project ID."}},"resources":[{"address":"google_compute_subnetwork_iam_member.cloudservices_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"cloudservices_shared_vpc_subnet_users","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.service_project_number"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role","local.subnetwork_api"]}},{"address":"google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_shared_vpc_subnet_users","provider_config_key":"module.seed_bootstrap.module.seed_project:google-beta","expressions":{"member":{"references":["local.apis","local.subnetwork_api","count.index"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"references":["local.apis","local.subnetwork_api","count.index"]},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","local.subnetwork_api"]}},{"address":"google_project_iam_member.composer_host_agent","mode":"managed","type":"google_project_iam_member","name":"composer_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"composer.googleapis.com\"].service_account","local.apis[\"composer.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/composer.sharedVpcAgent"}},"schema_version":0,"count_expression":{"references":["local.composer_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datasfusion_network_viewer","mode":"managed","type":"google_project_iam_member","name":"datasfusion_network_viewer","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datafusion.googleapis.com\"].service_account","local.apis[\"datafusion.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkViewer"}},"schema_version":0,"count_expression":{"references":["local.datafusion_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datastream_network_admin","mode":"managed","type":"google_project_iam_member","name":"datastream_network_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datastream.googleapis.com\"].service_account","local.apis[\"datastream.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkAdmin"}},"schema_version":0,"count_expression":{"references":["local.datastream_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_network_admin_role"]}},{"address":"google_project_iam_member.gke_host_agent","mode":"managed","type":"google_project_iam_member","name":"gke_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/container.hostServiceAgentUser"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.gke_security_admin","mode":"managed","type":"google_project_iam_member","name":"gke_security_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.securityAdmin"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_security_admin_role"]}},{"address":"google_project_iam_member.service_shared_vpc_user","mode":"managed","type":"google_project_iam_member","name":"service_shared_vpc_user","provider_config_key":"google","expressions":{"member":{"references":["local.apis","each.value"]},"project":{"references":["var.host_project_id"]},"role":{"references":["local.apis","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.shared_vpc_subnets","var.enable_shared_vpc_service_project","var.grant_network_role","local.active_apis"]}},{"address":"data.google_project.service_project","mode":"data","type":"google_project","name":"service_project","provider_config_key":"google","expressions":{"project_id":{"references":["var.service_project_id"]}},"schema_version":0,"count_expression":{"references":["var.lookup_project_numbers"]}}],"variables":{"active_apis":{"default":[],"description":"The list of active apis on the service project. If api is not active this module will not try to activate it"},"enable_shared_vpc_service_project":{"description":"Flag set if SVPC enabled"},"grant_network_role":{"default":true,"description":"Whether or not to grant service agents the network roles on the host project"},"grant_services_network_admin_role":{"default":false,"description":"Whether or not to grant Datastream Service acount the Network Admin role on the host project so it can manage firewall rules"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"host_project_id":{"description":"The ID of the host project which hosts the shared VPC"},"lookup_project_numbers":{"default":true,"description":"Whether to look up the project numbers from data sources. If false, `service_project_number` will be used instead."},"service_project_id":{"description":"The ID of the service project"},"service_project_number":{"default":null,"description":"Project number of the service project. Will be used if `lookup_service_project_number` is false."},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"}}},"depends_on":["module.project-factory.enabled_apis"]}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"budget_alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"budget_alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"budget_alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"budget_amount":{"default":null,"description":"The amount to use for a budget alert"},"budget_calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"budget_custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"budget_labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"budget_monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"consumer_quotas":{"default":[],"description":"The quotas configuration you want to override for the project."},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"domain":{"default":"","description":"The domain name (optional)."},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set svpc_host_project_id variable. Default is false."},"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"group_name":{"default":"","description":"A group to control the project by being assigned group_role (defaults to project editor)"},"group_role":{"default":"roles/editor","description":"The role to give the controlling group (group_name) over the project (defaults to project editor)"},"labels":{"default":{},"description":"Map of labels for project"},"language_tag":{"default":"en-US","description":"Language code to be used for essential contacts notifications"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"svpc_host_project_id":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}},"version_constraint":"~\u003e 18.0"}},"variables":{"activate_apis":{"default":["serviceusage.googleapis.com","servicenetworking.googleapis.com","compute.googleapis.com","logging.googleapis.com","bigquery.googleapis.com","cloudresourcemanager.googleapis.com","cloudbilling.googleapis.com","iam.googleapis.com","admin.googleapis.com","appengine.googleapis.com","storage-api.googleapis.com","monitoring.googleapis.com"],"description":"List of APIs to enable in the seed project."},"billing_account":{"description":"The ID of the billing account to associate projects with."},"create_terraform_sa":{"default":true,"description":"If the Terraform service account should be created."},"default_region":{"default":"us-central1","description":"Default region to create resources where applicable."},"encrypt_gcs_bucket_tfstate":{"default":false,"description":"Encrypt bucket used for storing terraform state files in seed project."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"force_destroy":{"default":false,"description":"If supplied, the state bucket will be deleted even while containing objects."},"grant_billing_user":{"default":true,"description":"Grant roles/billing.user role to CFT service account"},"group_billing_admins":{"description":"Google Group for GCP Billing Administrators"},"group_org_admins":{"description":"Google Group for GCP Organization Administrators"},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\"]"},"key_rotation_period":{"default":null,"description":"The rotation period of the key."},"kms_prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"org_admins_org_iam_permissions":{"default":["roles/billing.user","roles/resourcemanager.organizationAdmin"],"description":"List of permissions granted to the group supplied in group_org_admins variable across the GCP organization."},"org_id":{"description":"GCP Organization ID"},"org_project_creators":{"default":[],"description":"Additional list of members to have project creator role accross the organization. Prefix of group: user: or serviceAccount: is required."},"parent_folder":{"default":"","description":"GCP parent folder ID in the form folders/{id}"},"project_auto_create_network":{"default":false,"description":"Create the default network for the project created."},"project_deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project created."},"project_id":{"default":"","description":"Custom project ID to use for project created. If not supplied, the default id is {project_prefix}-seed-{random suffix}."},"project_labels":{"default":{},"description":"Labels to apply to the project."},"project_prefix":{"default":"cft","description":"Name prefix to use for projects created."},"random_suffix":{"default":true,"description":"Appends a 4 character random suffix to project ID and GCS bucket name."},"sa_enable_impersonation":{"default":false,"description":"Allow org_admins group to impersonate service account \u0026 enable APIs required."},"sa_org_iam_permissions":{"default":["roles/billing.user","roles/compute.networkAdmin","roles/compute.xpnAdmin","roles/iam.securityAdmin","roles/iam.serviceAccountAdmin","roles/logging.configWriter","roles/orgpolicy.policyAdmin","roles/resourcemanager.folderAdmin","roles/resourcemanager.organizationViewer"],"description":"List of permissions granted to Terraform service account across the GCP organization."},"state_bucket_name":{"default":"","description":"Custom state bucket name. If not supplied, the default name is {project_prefix}-tfstate-{random suffix}."},"storage_bucket_labels":{"default":{},"description":"Labels to apply to the storage bucket."},"tf_service_account_id":{"default":"org-terraform","description":"ID of service account for terraform in seed project"},"tf_service_account_name":{"default":"CFT Organization Terraform Account","description":"Display name of service account for terraform in seed project"}}},"version_constraint":"~\u003e 11.0","depends_on":["module.required_group"]},"seed_project_iam_member":{"source":"./modules/parent-iam-member","expressions":{"member":{"references":["google_service_account.terraform-env-sa","each.key"]},"parent_id":{"references":["module.seed_bootstrap.seed_project_id","module.seed_bootstrap"]},"parent_type":{"constant_value":"project"},"roles":{"references":["each.value"]}},"for_each_expression":{"references":["local.granular_sa_seed_project"]},"module":{"resources":[{"address":"google_folder_iam_member.folder_parent_iam","mode":"managed","type":"google_folder_iam_member","name":"folder_parent_iam","provider_config_key":"google","expressions":{"folder":{"references":["local.folder_id"]},"member":{"references":["var.member"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_organization_iam_member.org_parent_iam","mode":"managed","type":"google_organization_iam_member","name":"org_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"org_id":{"references":["local.org_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}},{"address":"google_project_iam_member.project_parent_iam","mode":"managed","type":"google_project_iam_member","name":"project_parent_iam","provider_config_key":"google","expressions":{"member":{"references":["var.member"]},"project":{"references":["local.project_id"]},"role":{"references":["each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.parent_type","var.roles"]}}],"variables":{"member":{"description":"Member to have the given roles in the parent resource. Prefix of `group:`, `user:` or `serviceAccount:` is required."},"parent_id":{"description":"ID of the parent resource."},"parent_type":{"description":"Type of the parent resource. valid values are `organization`, `folder`, and `project`."},"roles":{"description":"Roles to grant to the member in the parent resource."}}}},"tf_cloud_builder":{"source":"terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_builder","expressions":{"bucket_name":{"references":["var.bucket_prefix","module.tf_source.cloudbuild_project_id","module.tf_source"]},"build_timeout":{"constant_value":"1200s"},"cb_logs_bucket_force_destroy":{"references":["var.bucket_force_destroy"]},"dockerfile_repo_uri":{"references":["module.tf_source.csr_repos","module.tf_source","local.cloudbuilder_repo"]},"enable_worker_pool":{"constant_value":true},"gar_repo_location":{"references":["var.default_region"]},"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"terraform_version":{"references":["local.terraform_version"]},"trigger_location":{"references":["var.default_region"]},"worker_pool_id":{"references":["module.tf_private_pool.private_worker_pool_id","module.tf_private_pool"]},"workflow_deletion_protection":{"references":["var.workflow_deletion_protection"]},"workflow_region":{"references":["var.default_region"]}},"module":{"outputs":{"artifact_repo":{"expression":{"references":["google_artifact_registry_repository.tf-image-repo.name","google_artifact_registry_repository.tf-image-repo"]},"description":"GAR Repo created to store TF Cloud Builder images"},"cloudbuild_sa":{"expression":{"references":["local.cloudbuild_sa"]},"description":"SA used by Cloud Build trigger"},"cloudbuild_trigger_id":{"expression":{"references":["google_cloudbuild_trigger.build_trigger.id","google_cloudbuild_trigger.build_trigger"]},"description":"Trigger used for building new TF Builder"},"scheduler_id":{"expression":{"references":["google_cloud_scheduler_job.trigger_workflow.id","google_cloud_scheduler_job.trigger_workflow"]},"description":"Scheduler ID for periodically triggering TF Builder build Workflow"},"workflow_id":{"expression":{"references":["google_workflows_workflow.builder.id","google_workflows_workflow.builder"]},"description":"Workflow ID for triggering new TF Builder build"},"workflow_sa":{"expression":{"references":["local.workflow_sa"]},"description":"SA used by Workflow for triggering new TF Builder build"}},"resources":[{"address":"google_artifact_registry_repository.tf-image-repo","mode":"managed","type":"google_artifact_registry_repository","name":"tf-image-repo","provider_config_key":"google-beta","expressions":{"description":{"constant_value":"Docker repository for Terraform runner images used by Cloud Build. Managed by Terraform."},"format":{"constant_value":"DOCKER"},"location":{"references":["var.gar_repo_location"]},"project":{"references":["var.project_id"]},"repository_id":{"references":["var.gar_repo_name"]}},"schema_version":0},{"address":"google_artifact_registry_repository_iam_member.push_images","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"push_images","provider_config_key":"google-beta","expressions":{"location":{"references":["google_artifact_registry_repository.tf-image-repo.location","google_artifact_registry_repository.tf-image-repo"]},"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["var.project_id"]},"repository":{"references":["google_artifact_registry_repository.tf-image-repo.name","google_artifact_registry_repository.tf-image-repo"]},"role":{"constant_value":"roles/artifactregistry.writer"}},"schema_version":0},{"address":"google_artifact_registry_repository_iam_member.workflow_list","mode":"managed","type":"google_artifact_registry_repository_iam_member","name":"workflow_list","provider_config_key":"google-beta","expressions":{"location":{"references":["google_artifact_registry_repository.tf-image-repo.location","google_artifact_registry_repository.tf-image-repo"]},"member":{"references":["local.workflow_sa"]},"project":{"references":["var.project_id"]},"repository":{"references":["google_artifact_registry_repository.tf-image-repo.name","google_artifact_registry_repository.tf-image-repo"]},"role":{"constant_value":"roles/artifactregistry.reader"}},"schema_version":0},{"address":"google_cloud_scheduler_job.trigger_workflow","mode":"managed","type":"google_cloud_scheduler_job","name":"trigger_workflow","provider_config_key":"google","expressions":{"description":{"constant_value":"Trigger workflow for TF Runner builds. Managed by Terraform."},"http_target":[{"http_method":{"constant_value":"POST"},"oauth_token":[{"scope":{"constant_value":"https://www.googleapis.com/auth/cloud-platform"},"service_account_email":{"references":["local.workflow_sa"]}}],"uri":{"references":["google_workflows_workflow.builder.id","google_workflows_workflow.builder"]}}],"name":{"references":["var.workflow_name"]},"project":{"references":["var.project_id"]},"region":{"references":["var.workflow_region"]},"schedule":{"references":["var.workflow_schedule"]},"time_zone":{"constant_value":"Etc/UTC"}},"schema_version":0},{"address":"google_cloudbuild_trigger.build_trigger","mode":"managed","type":"google_cloudbuild_trigger","name":"build_trigger","provider_config_key":"google","expressions":{"build":[{"images":{"references":["local.img_tags_subst"]},"logs_bucket":{"references":["module.bucket.bucket.url","module.bucket.bucket","module.bucket"]},"step":[{"args":{"references":["local.img_tags_subst"]},"dir":{"references":["var.dockerfile_repo_dir","var.dockerfile_repo_dir"]},"name":{"constant_value":"gcr.io/cloud-builders/docker"}},{"args":{"constant_value":["version"]},"name":{"references":["local.gar_uri"]}}],"timeout":{"references":["var.build_timeout"]}}],"description":{"constant_value":"Builds a Terraform runner image. Managed by Terraform."},"location":{"references":["var.trigger_location"]},"name":{"references":["var.trigger_name"]},"project":{"references":["var.project_id"]},"service_account":{"references":["local.cloudbuild_sa"]},"substitutions":{"references":["local.tags_subst"]}},"schema_version":2,"depends_on":["google_artifact_registry_repository_iam_member.push_images","google_project_iam_member.logs_writer"]},{"address":"google_project_iam_member.invoke_workflow_scheduler","mode":"managed","type":"google_project_iam_member","name":"invoke_workflow_scheduler","provider_config_key":"google","expressions":{"member":{"references":["local.workflow_sa"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/workflows.invoker"}},"schema_version":0},{"address":"google_project_iam_member.logs_writer","mode":"managed","type":"google_project_iam_member","name":"logs_writer","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/logging.logWriter"}},"schema_version":0},{"address":"google_project_iam_member.trigger_builds","mode":"managed","type":"google_project_iam_member","name":"trigger_builds","provider_config_key":"google","expressions":{"member":{"references":["local.workflow_sa"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/cloudbuild.builds.editor"}},"schema_version":0},{"address":"google_service_account.cb_sa","mode":"managed","type":"google_service_account","name":"cb_sa","provider_config_key":"google","expressions":{"account_id":{"constant_value":"tf-cb-builder-sa"},"create_ignore_already_exists":{"constant_value":true},"display_name":{"constant_value":"SA for Terraform builder build trigger. Managed by Terraform."},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.cloudbuild_sa"]}},{"address":"google_service_account.workflow_sa","mode":"managed","type":"google_service_account","name":"workflow_sa","provider_config_key":"google","expressions":{"account_id":{"constant_value":"terraform-runner-workflow-sa"},"create_ignore_already_exists":{"constant_value":true},"display_name":{"constant_value":"SA for TF Builder Workflow. Managed by Terraform."},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.workflow_sa"]}},{"address":"google_service_account_iam_member.use_cb_sa","mode":"managed","type":"google_service_account_iam_member","name":"use_cb_sa","provider_config_key":"google","expressions":{"member":{"references":["local.workflow_sa"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["local.cloudbuild_sa"]}},"schema_version":0},{"address":"google_sourcerepo_repository_iam_member.member","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["local.source_repo_project"]},"repository":{"references":["local.source_repo_name"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0,"count_expression":{"references":["local.is_source_repo"]}},{"address":"google_storage_bucket_iam_member.member","mode":"managed","type":"google_storage_bucket_iam_member","name":"member","provider_config_key":"google","expressions":{"bucket":{"references":["module.bucket.bucket.self_link","module.bucket.bucket","module.bucket"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"google_workflows_workflow.builder","mode":"managed","type":"google_workflows_workflow","name":"builder","provider_config_key":"google","expressions":{"deletion_protection":{"references":["var.workflow_deletion_protection"]},"description":{"constant_value":"Workflow for triggering TF Runner builds. Managed by Terraform."},"name":{"references":["var.workflow_name"]},"project":{"references":["var.project_id"]},"region":{"references":["var.workflow_region"]},"service_account":{"references":["local.workflow_sa"]},"source_contents":{"references":["local.rendered_workflow_config"]}},"schema_version":1}],"module_calls":{"bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.cb_logs_bucket_force_destroy"]},"location":{"references":["var.gar_repo_location"]},"name":{"references":["local.log_bucket_name"]},"project_id":{"references":["var.project_id"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"}},"variables":{"bucket_name":{"default":"","description":"Custom bucket name for Cloud Build logs."},"build_timeout":{"default":"600s","description":"Amount of time the build should be allowed to run, to second granularity. Format is the number of seconds followed by s."},"cb_logs_bucket_force_destroy":{"default":false,"description":"When deleting the bucket for storing CloudBuild logs, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"cloudbuild_sa":{"default":"","description":"Custom SA email to be used by the CloudBuild trigger. Defaults to being created if empty."},"dockerfile_repo_dir":{"default":"","description":"The directory inside the repo where the Dockerfile is located. If empty defaults to repo root."},"dockerfile_repo_ref":{"default":"refs/heads/main","description":"The branch or tag to use. Use refs/heads/branchname for branches or refs/tags/tagname for tags."},"dockerfile_repo_type":{"default":"CLOUD_SOURCE_REPOSITORIES","description":"Type of repo"},"dockerfile_repo_uri":{"default":"","description":"The URI of the repo where the Dockerfile for Terraform builder is stored. If using Cloud Build Repositories (2nd Gen) this is the repository ID where the Dockerfile is stored. Repository ID Format is 'projects/{{project}}/locations/{{location}}/connections/{{parent_connection}}/repositories/{{name}}'"},"enable_worker_pool":{"default":false,"description":"Set to true to use a private worker pool in the Cloud Build Trigger."},"gar_repo_location":{"description":"Name of the location for the Google Artifact Repository."},"gar_repo_name":{"default":"tf-runners","description":"Name of the Google Artifact Repository where the Terraform builder images are stored."},"image_name":{"default":"terraform","description":"Name of the image for the Terraform builder."},"project_id":{"description":"GCP project for Cloud Build trigger,workflow and scheduler."},"terraform_version":{"default":"1.1.0","description":"The initial terraform version in semantic version format."},"trigger_location":{"description":"Location of the Cloud Build trigger building the Terraform builder. If using private pools should be the same location as the pool."},"trigger_name":{"default":"tf-cloud-builder-build","description":"Name of the Cloud Build trigger building the Terraform builder."},"use_cloudbuildv2_repository":{"default":false,"description":"Use Cloud Build repository (2nd gen)"},"worker_pool_id":{"default":"","description":"Custom private worker pool ID. Format: 'projects/PROJECT_ID/locations/REGION/workerPools/PRIVATE_POOL_ID'."},"workflow_deletion_protection":{"default":true,"description":"Whether Terraform will be prevented from destroying the workflow. When the field is set to true or unset in Terraform state, a `terraform apply` or `terraform destroy` that would delete the workflow will fail. When the field is set to false, deleting the workflow is allowed."},"workflow_name":{"default":"terraform-runner-workflow","description":"Name of the workflow managing builds."},"workflow_region":{"default":"us-central1","description":"The region of the workflow."},"workflow_sa":{"default":"","description":"Custom SA email to be used by the workflow. Defaults to being created if empty."},"workflow_schedule":{"default":"0 8 * * *","description":"The workflow frequency, in cron syntax"}}},"version_constraint":"~\u003e 11.0"},"tf_private_pool":{"source":"./modules/cb-private-pool","expressions":{"private_worker_pool":{"references":["var.default_region"]},"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"vpn_configuration":{"constant_value":{"enable_vpn":false}}},"module":{"outputs":{"peered_network_id":{"expression":{"references":["local.peered_network_id"]},"description":"The ID of the peered network."},"private_worker_pool_id":{"expression":{"references":["google_cloudbuild_worker_pool.private_pool.id","google_cloudbuild_worker_pool.private_pool"]},"description":"Private worker pool ID."},"worker_peered_ip_range":{"expression":{"references":["local.peered_ip_range"]},"description":"The IP range of the peered service network."},"worker_range_id":{"expression":{"references":["google_compute_global_address.worker_pool_range[0].id","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range"]},"description":"The worker IP range ID."}},"resources":[{"address":"google_cloudbuild_worker_pool.private_pool","mode":"managed","type":"google_cloudbuild_worker_pool","name":"private_pool","provider_config_key":"google","expressions":{"location":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"name":{"references":["local.private_pool_name"]},"project":{"references":["var.project_id"]},"worker_config":[{"disk_size_gb":{"references":["var.private_worker_pool.disk_size_gb","var.private_worker_pool"]},"machine_type":{"references":["var.private_worker_pool.machine_type","var.private_worker_pool"]},"no_external_ip":{"references":["var.private_worker_pool.no_external_ip","var.private_worker_pool"]}}]},"schema_version":0,"depends_on":["google_compute_global_address.worker_pool_range","google_service_networking_connection.worker_pool_conn"]},{"address":"google_compute_address.cloud_build_nat","mode":"managed","type":"google_compute_address","name":"cloud_build_nat","provider_config_key":"google","expressions":{"address_type":{"constant_value":"EXTERNAL"},"name":{"constant_value":"cloud-build-nat"},"network_tier":{"constant_value":"PREMIUM"},"project":{"references":["var.project_id"]},"region":{"constant_value":"us-central1"}},"schema_version":0},{"address":"google_compute_global_address.worker_pool_range","mode":"managed","type":"google_compute_global_address","name":"worker_pool_range","provider_config_key":"google","expressions":{"address":{"references":["var.private_worker_pool.peering_address","var.private_worker_pool"]},"address_type":{"constant_value":"INTERNAL"},"name":{"constant_value":"ga-b-cbpools-worker-pool-range"},"network":{"references":["local.peered_network_id"]},"prefix_length":{"references":["var.private_worker_pool.peering_prefix_length","var.private_worker_pool"]},"project":{"references":["var.project_id"]},"purpose":{"constant_value":"VPC_PEERING"}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]}},{"address":"google_compute_instance.vm-proxy","mode":"managed","type":"google_compute_instance","name":"vm-proxy","provider_config_key":"google","expressions":{"boot_disk":[{"initialize_params":[{"image":{"constant_value":"debian-cloud/debian-12"}}]}],"can_ip_forward":{"constant_value":true},"machine_type":{"constant_value":"e2-medium"},"metadata_startup_script":{"constant_value":"sysctl -w net.ipv4.ip_forward=1 \u0026\u0026 iptables -t nat -A POSTROUTING -o $(ip addr show scope global | head -1 | awk -F: '{print $2}') -j MASQUERADE"},"name":{"constant_value":"cloud-build-nat-vm"},"network_interface":[{"network":{"references":["local.peered_network_name"]},"subnetwork":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"subnetwork_project":{"references":["var.project_id"]}}],"project":{"references":["var.project_id"]},"service_account":[{"scopes":{"constant_value":["cloud-platform"]}}],"tags":{"constant_value":["direct-gateway-access","nat-gateway"]},"zone":{"constant_value":"us-central1-a"}},"schema_version":6,"depends_on":["google_compute_router_nat.cb-nat"]},{"address":"google_compute_network_peering_routes_config.peering_routes","mode":"managed","type":"google_compute_network_peering_routes_config","name":"peering_routes","provider_config_key":"google","expressions":{"export_custom_routes":{"constant_value":true},"import_custom_routes":{"constant_value":true},"network":{"references":["local.peered_network_name"]},"peering":{"references":["google_service_networking_connection.worker_pool_conn[0].peering","google_service_networking_connection.worker_pool_conn[0]","google_service_networking_connection.worker_pool_conn"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]}},{"address":"google_compute_route.direct-to-gateway","mode":"managed","type":"google_compute_route","name":"direct-to-gateway","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"0.0.0.0/1"},"name":{"constant_value":"direct-to-gateway-range1"},"network":{"references":["local.peered_network_name"]},"next_hop_gateway":{"constant_value":"default-internet-gateway"},"priority":{"constant_value":5},"project":{"references":["var.project_id"]},"tags":{"constant_value":["direct-gateway-access"]}},"schema_version":0},{"address":"google_compute_route.direct-to-gateway2","mode":"managed","type":"google_compute_route","name":"direct-to-gateway2","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"128.0.0.0/1"},"name":{"constant_value":"direct-to-gateway-range2"},"network":{"references":["local.peered_network_name"]},"next_hop_gateway":{"constant_value":"default-internet-gateway"},"priority":{"constant_value":5},"project":{"references":["var.project_id"]},"tags":{"constant_value":["direct-gateway-access"]}},"schema_version":0},{"address":"google_compute_route.through-nat","mode":"managed","type":"google_compute_route","name":"through-nat","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"0.0.0.0/1"},"name":{"constant_value":"through-nat-range1"},"network":{"references":["local.peered_network_name"]},"next_hop_instance":{"references":["google_compute_instance.vm-proxy.id","google_compute_instance.vm-proxy"]},"priority":{"constant_value":10},"project":{"references":["var.project_id"]}},"schema_version":0},{"address":"google_compute_route.through-nat2","mode":"managed","type":"google_compute_route","name":"through-nat2","provider_config_key":"google","expressions":{"dest_range":{"constant_value":"128.0.0.0/1"},"name":{"constant_value":"through-nat-range2"},"network":{"references":["local.peered_network_name"]},"next_hop_instance":{"references":["google_compute_instance.vm-proxy.id","google_compute_instance.vm-proxy"]},"priority":{"constant_value":10},"project":{"references":["var.project_id"]}},"schema_version":0},{"address":"google_compute_router.cb-router","mode":"managed","type":"google_compute_router","name":"cb-router","provider_config_key":"google","expressions":{"name":{"constant_value":"cb-cloud-router"},"network":{"references":["local.peered_network_name"]},"project":{"references":["var.project_id"]},"region":{"constant_value":"us-central1"}},"schema_version":0},{"address":"google_compute_router_nat.cb-nat","mode":"managed","type":"google_compute_router_nat","name":"cb-nat","provider_config_key":"google","expressions":{"log_config":[{"enable":{"constant_value":true},"filter":{"constant_value":"ALL"}}],"name":{"constant_value":"cb-cloud-nat"},"nat_ip_allocate_option":{"constant_value":"AUTO_ONLY"},"project":{"references":["var.project_id"]},"region":{"references":["google_compute_router.cb-router.region","google_compute_router.cb-router"]},"router":{"references":["google_compute_router.cb-router.name","google_compute_router.cb-router"]},"source_subnetwork_ip_ranges_to_nat":{"constant_value":"ALL_SUBNETWORKS_ALL_IP_RANGES"}},"schema_version":0},{"address":"google_dns_policy.default_policy","mode":"managed","type":"google_dns_policy","name":"default_policy","provider_config_key":"google","expressions":{"enable_inbound_forwarding":{"constant_value":true},"enable_logging":{"constant_value":true},"name":{"constant_value":"dp-b-cbpools-default-policy"},"networks":[{"network_url":{"references":["module.peered_network[0].network_self_link","module.peered_network[0]"]}}],"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.create_peered_network","var.private_worker_pool"]}},{"address":"google_service_networking_connection.worker_pool_conn","mode":"managed","type":"google_service_networking_connection","name":"worker_pool_conn","provider_config_key":"google","expressions":{"network":{"references":["local.peered_network_id"]},"reserved_peering_ranges":{"references":["google_compute_global_address.worker_pool_range[0].name","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range"]},"service":{"constant_value":"servicenetworking.googleapis.com"}},"schema_version":0,"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]}},{"address":"random_string.suffix","mode":"managed","type":"random_string","name":"suffix","provider_config_key":"random","expressions":{"length":{"constant_value":4},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2},{"address":"data.google_secret_manager_secret_version.psk","mode":"data","type":"google_secret_manager_secret_version","name":"psk","provider_config_key":"google","expressions":{"project":{"references":["var.vpn_configuration.psk_secret_project_id","var.vpn_configuration"]},"secret":{"references":["var.vpn_configuration.psk_secret_name","var.vpn_configuration"]}},"schema_version":0,"count_expression":{"references":["var.vpn_configuration.enable_vpn","var.vpn_configuration"]}}],"module_calls":{"firewall_rules":{"source":"terraform-google-modules/network/google//modules/firewall-rules","expressions":{"network_name":{"references":["local.peered_network_id"]},"project_id":{"references":["var.project_id"]},"rules":{"references":["local.peered_ip_range","google_compute_global_address.worker_pool_range[0].address","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range","google_compute_global_address.worker_pool_range[0].prefix_length","google_compute_global_address.worker_pool_range[0]","google_compute_global_address.worker_pool_range"]}},"count_expression":{"references":["var.private_worker_pool.enable_network_peering","var.private_worker_pool"]},"module":{"outputs":{"firewall_rules":{"expression":{"references":["google_compute_firewall.rules"]},"description":"The created firewall rule resources"},"firewall_rules_ingress_egress":{"expression":{"references":["google_compute_firewall.rules_ingress_egress"]},"description":"The created firewall ingress/egress rule resources"}},"resources":[{"address":"google_compute_firewall.rules","mode":"managed","type":"google_compute_firewall","name":"rules","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","var.rules"]}},{"address":"google_compute_firewall.rules_ingress_egress","mode":"managed","type":"google_compute_firewall","name":"rules_ingress_egress","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","local.rules_all"]}}],"variables":{"egress_rules":{"default":[],"description":"List of egress rules. This will be ignored if variable 'rules' is non-empty"},"ingress_rules":{"default":[],"description":"List of ingress rules. This will be ignored if variable 'rules' is non-empty"},"network_name":{"description":"Name of the network this set of firewall rules applies to."},"project_id":{"description":"Project id of the project that holds the network."},"rules":{"default":[],"description":"This is DEPRICATED and available for backward compatiblity. Use ingress_rules and egress_rules variables. List of custom rule definitions"}}},"version_constraint":"~\u003e 10.0"},"peered_network":{"source":"terraform-google-modules/network/google","expressions":{"delete_default_internet_gateway_routes":{"constant_value":"true"},"network_name":{"references":["local.network_name"]},"project_id":{"references":["var.project_id"]},"subnets":{"references":["var.private_worker_pool.region","var.private_worker_pool","var.private_worker_pool.peered_network_subnet_ip","var.private_worker_pool","var.private_worker_pool.region","var.private_worker_pool","var.vpc_flow_logs.aggregation_interval","var.vpc_flow_logs","var.vpc_flow_logs.flow_sampling","var.vpc_flow_logs","var.vpc_flow_logs.metadata","var.vpc_flow_logs","var.vpc_flow_logs.metadata_fields","var.vpc_flow_logs","var.vpc_flow_logs.filter_expr","var.vpc_flow_logs"]}},"count_expression":{"references":["var.private_worker_pool.create_peered_network","var.private_worker_pool"]},"module":{"outputs":{"network":{"expression":{"references":["module.vpc"]},"description":"The created network"},"network_id":{"expression":{"references":["module.vpc.network_id","module.vpc"]},"description":"The ID of the VPC being created"},"network_name":{"expression":{"references":["module.vpc.network_name","module.vpc"]},"description":"The name of the VPC being created"},"network_self_link":{"expression":{"references":["module.vpc.network_self_link","module.vpc"]},"description":"The URI of the VPC being created"},"project_id":{"expression":{"references":["module.vpc.project_id","module.vpc"]},"description":"VPC project id"},"route_names":{"expression":{"references":["module.routes.routes","module.routes"]},"description":"The route names associated with this VPC"},"subnets":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"A map with keys of form subnet_region/subnet_name and values being the outputs of the google_compute_subnetwork resources used to create corresponding subnets."},"subnets_flow_logs":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"Whether the subnets will have VPC flow logs enabled"},"subnets_ids":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The IDs of the subnets being created"},"subnets_ips":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The IPs and CIDRs of the subnets being created"},"subnets_names":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The names of the subnets being created"},"subnets_private_access":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"Whether the subnets will have access to Google API's without a public IP"},"subnets_regions":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The region where the subnets will be created"},"subnets_secondary_ranges":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The secondary ranges associated with these subnets"},"subnets_self_links":{"expression":{"references":["module.subnets.subnets","module.subnets"]},"description":"The self-links of subnets being created"}},"module_calls":{"firewall_rules":{"source":"./modules/firewall-rules","expressions":{"egress_rules":{"references":["var.egress_rules"]},"ingress_rules":{"references":["var.ingress_rules"]},"network_name":{"references":["module.vpc.network_name","module.vpc"]},"project_id":{"references":["var.project_id"]},"rules":{"references":["local.rules"]}},"module":{"outputs":{"firewall_rules":{"expression":{"references":["google_compute_firewall.rules"]},"description":"The created firewall rule resources"},"firewall_rules_ingress_egress":{"expression":{"references":["google_compute_firewall.rules_ingress_egress"]},"description":"The created firewall ingress/egress rule resources"}},"resources":[{"address":"google_compute_firewall.rules","mode":"managed","type":"google_compute_firewall","name":"rules","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value.direction","each.value","each.value.ranges","each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","var.rules"]}},{"address":"google_compute_firewall.rules_ingress_egress","mode":"managed","type":"google_compute_firewall","name":"rules_ingress_egress","provider_config_key":"google","expressions":{"description":{"references":["each.value.description","each.value"]},"destination_ranges":{"references":["each.value"]},"direction":{"references":["each.value.direction","each.value"]},"disabled":{"references":["each.value.disabled","each.value"]},"name":{"references":["each.value.name","each.value"]},"network":{"references":["var.network_name"]},"priority":{"references":["each.value.priority","each.value"]},"project":{"references":["var.project_id"]},"source_ranges":{"references":["each.value"]},"source_service_accounts":{"references":["each.value.source_service_accounts","each.value"]},"source_tags":{"references":["each.value.source_tags","each.value"]},"target_service_accounts":{"references":["each.value.target_service_accounts","each.value"]},"target_tags":{"references":["each.value.target_tags","each.value"]}},"schema_version":1,"for_each_expression":{"references":["var.rules","local.rules_all"]}}],"variables":{"egress_rules":{"default":[],"description":"List of egress rules. This will be ignored if variable 'rules' is non-empty"},"ingress_rules":{"default":[],"description":"List of ingress rules. This will be ignored if variable 'rules' is non-empty"},"network_name":{"description":"Name of the network this set of firewall rules applies to."},"project_id":{"description":"Project id of the project that holds the network."},"rules":{"default":[],"description":"This is DEPRICATED and available for backward compatiblity. Use ingress_rules and egress_rules variables. List of custom rule definitions"}}}},"routes":{"source":"./modules/routes","expressions":{"module_depends_on":{"references":["module.subnets.subnets","module.subnets"]},"network_name":{"references":["module.vpc.network_name","module.vpc"]},"project_id":{"references":["var.project_id"]},"routes":{"references":["var.routes"]}},"module":{"outputs":{"routes":{"expression":{"references":["google_compute_route.route"]},"description":"The created routes resources"}},"resources":[{"address":"google_compute_route.route","mode":"managed","type":"google_compute_route","name":"route","provider_config_key":"google","expressions":{"description":{"references":["each.value"]},"dest_range":{"references":["each.value"]},"name":{"references":["each.key"]},"network":{"references":["var.network_name"]},"next_hop_gateway":{"references":["each.value"]},"next_hop_ilb":{"references":["each.value"]},"next_hop_instance":{"references":["each.value"]},"next_hop_instance_zone":{"references":["each.value"]},"next_hop_ip":{"references":["each.value"]},"next_hop_vpn_tunnel":{"references":["each.value"]},"priority":{"references":["each.value"]},"project":{"references":["var.project_id"]},"tags":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.routes"]},"depends_on":["var.module_depends_on"]}],"variables":{"module_depends_on":{"default":[],"description":"List of modules or resources this module depends on."},"network_name":{"description":"The name of the network where routes will be created"},"project_id":{"description":"The ID of the project where the routes will be created"},"routes":{"default":[],"description":"List of routes being created in this VPC"}}}},"subnets":{"source":"./modules/subnets","expressions":{"network_name":{"references":["module.vpc.network_name","module.vpc"]},"project_id":{"references":["var.project_id"]},"secondary_ranges":{"references":["var.secondary_ranges"]},"subnets":{"references":["var.subnets"]}},"module":{"outputs":{"subnets":{"expression":{"references":["google_compute_subnetwork.subnetwork"]},"description":"The created subnet resources"}},"resources":[{"address":"google_compute_subnetwork.subnetwork","mode":"managed","type":"google_compute_subnetwork","name":"subnetwork","provider_config_key":"google","expressions":{"description":{"references":["each.value"]},"ip_cidr_range":{"references":["each.value.subnet_ip","each.value"]},"ipv6_access_type":{"references":["each.value"]},"name":{"references":["each.value.subnet_name","each.value"]},"network":{"references":["var.network_name"]},"private_ip_google_access":{"references":["each.value"]},"private_ipv6_google_access":{"references":["each.value"]},"project":{"references":["var.project_id"]},"purpose":{"references":["each.value"]},"region":{"references":["each.value.subnet_region","each.value"]},"role":{"references":["each.value"]},"stack_type":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.subnets"]}}],"variables":{"network_name":{"description":"The name of the network where subnets will be created"},"project_id":{"description":"The ID of the project where subnets will be created"},"secondary_ranges":{"default":{},"description":"Secondary ranges that will be used in some of the subnets"},"subnets":{"description":"The list of subnets being created"}}}},"vpc":{"source":"./modules/vpc","expressions":{"auto_create_subnetworks":{"references":["var.auto_create_subnetworks"]},"delete_default_internet_gateway_routes":{"references":["var.delete_default_internet_gateway_routes"]},"description":{"references":["var.description"]},"enable_ipv6_ula":{"references":["var.enable_ipv6_ula"]},"internal_ipv6_range":{"references":["var.internal_ipv6_range"]},"mtu":{"references":["var.mtu"]},"network_firewall_policy_enforcement_order":{"references":["var.network_firewall_policy_enforcement_order"]},"network_name":{"references":["var.network_name"]},"network_profile":{"references":["var.network_profile"]},"project_id":{"references":["var.project_id"]},"routing_mode":{"references":["var.routing_mode"]},"shared_vpc_host":{"references":["var.shared_vpc_host"]}},"module":{"outputs":{"network":{"expression":{"references":["google_compute_network.network"]},"description":"The VPC resource being created"},"network_id":{"expression":{"references":["google_compute_network.network.id","google_compute_network.network"]},"description":"The ID of the VPC being created"},"network_name":{"expression":{"references":["google_compute_network.network.name","google_compute_network.network"]},"description":"The name of the VPC being created"},"network_self_link":{"expression":{"references":["google_compute_network.network.self_link","google_compute_network.network"]},"description":"The URI of the VPC being created"},"project_id":{"expression":{"references":["var.shared_vpc_host","google_compute_shared_vpc_host_project.shared_vpc_host","google_compute_shared_vpc_host_project.shared_vpc_host[0].project","google_compute_shared_vpc_host_project.shared_vpc_host[0]","google_compute_shared_vpc_host_project.shared_vpc_host","google_compute_network.network.project","google_compute_network.network"]},"description":"VPC project id"}},"resources":[{"address":"google_compute_network.network","mode":"managed","type":"google_compute_network","name":"network","provider_config_key":"google-beta","expressions":{"auto_create_subnetworks":{"references":["var.auto_create_subnetworks"]},"delete_default_routes_on_create":{"references":["var.delete_default_internet_gateway_routes"]},"description":{"references":["var.description"]},"enable_ula_internal_ipv6":{"references":["var.enable_ipv6_ula"]},"internal_ipv6_range":{"references":["var.internal_ipv6_range"]},"mtu":{"references":["var.mtu"]},"name":{"references":["var.network_name"]},"network_firewall_policy_enforcement_order":{"references":["var.network_firewall_policy_enforcement_order"]},"network_profile":{"references":["var.network_profile"]},"project":{"references":["var.project_id"]},"routing_mode":{"references":["var.routing_mode"]}},"schema_version":0},{"address":"google_compute_shared_vpc_host_project.shared_vpc_host","mode":"managed","type":"google_compute_shared_vpc_host_project","name":"shared_vpc_host","provider_config_key":"google-beta","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.shared_vpc_host"]},"depends_on":["google_compute_network.network"]}],"variables":{"auto_create_subnetworks":{"default":false,"description":"When set to true, the network is created in 'auto subnet mode' and it will create a subnet for each region automatically across the 10.128.0.0/9 address range. When set to false, the network is created in 'custom subnet mode' so the user can explicitly connect subnetwork resources."},"delete_default_internet_gateway_routes":{"default":false,"description":"If set, ensure that all routes within the network specified whose names begin with 'default-route' and with a next hop of 'default-internet-gateway' are deleted"},"description":{"default":"","description":"An optional description of this resource. The resource must be recreated to modify this field."},"enable_ipv6_ula":{"default":false,"description":"Enabled IPv6 ULA, this is a permenant change and cannot be undone! (default 'false')"},"internal_ipv6_range":{"default":null,"description":"When enabling IPv6 ULA, optionally, specify a /48 from fd20::/20 (default null)"},"mtu":{"default":0,"description":"The network MTU (If set to 0, meaning MTU is unset - defaults to '1460'). Recommended values: 1460 (default for historic reasons), 1500 (Internet default), or 8896 (for Jumbo packets). Allowed are all values in the range 1300 to 8896, inclusively."},"network_firewall_policy_enforcement_order":{"default":null,"description":"Set the order that Firewall Rules and Firewall Policies are evaluated. Valid values are `BEFORE_CLASSIC_FIREWALL` and `AFTER_CLASSIC_FIREWALL`. (default null or equivalent to `AFTER_CLASSIC_FIREWALL`)"},"network_name":{"description":"The name of the network being created"},"network_profile":{"default":null,"description":"\"A full or partial URL of the network profile to apply to this network.\nThis field can be set only at resource creation time. For example, the\nfollowing are valid URLs:\n * https://www.googleapis.com/compute/beta/projects/{projectId}/global/networkProfiles/{network_profile_name}\n * projects/{projectId}/global/networkProfiles/{network_profile_name}\n"},"project_id":{"description":"The ID of the project where this VPC will be created"},"routing_mode":{"default":"GLOBAL","description":"The network routing mode (default 'GLOBAL')"},"shared_vpc_host":{"default":false,"description":"Makes this project a Shared VPC host if 'true' (default 'false')"}}}}},"variables":{"auto_create_subnetworks":{"default":false,"description":"When set to true, the network is created in 'auto subnet mode' and it will create a subnet for each region automatically across the 10.128.0.0/9 address range. When set to false, the network is created in 'custom subnet mode' so the user can explicitly connect subnetwork resources."},"delete_default_internet_gateway_routes":{"default":false,"description":"If set, ensure that all routes within the network specified whose names begin with 'default-route' and with a next hop of 'default-internet-gateway' are deleted"},"description":{"default":"","description":"An optional description of this resource. The resource must be recreated to modify this field."},"egress_rules":{"default":[],"description":"List of egress rules. This will be ignored if variable 'rules' is non-empty"},"enable_ipv6_ula":{"default":false,"description":"Enabled IPv6 ULA, this is a permenant change and cannot be undone! (default 'false')"},"firewall_rules":{"default":[],"description":"This is DEPRICATED and available for backward compatiblity. Use ingress_rules and egress_rules variables. List of firewall rules"},"ingress_rules":{"default":[],"description":"List of ingress rules. This will be ignored if variable 'rules' is non-empty"},"internal_ipv6_range":{"default":null,"description":"When enabling IPv6 ULA, optionally, specify a /48 from fd20::/20 (default null)"},"mtu":{"default":0,"description":"The network MTU (If set to 0, meaning MTU is unset - defaults to '1460'). Recommended values: 1460 (default for historic reasons), 1500 (Internet default), or 8896 (for Jumbo packets). Allowed are all values in the range 1300 to 8896, inclusively."},"network_firewall_policy_enforcement_order":{"default":null,"description":"Set the order that Firewall Rules and Firewall Policies are evaluated. Valid values are `BEFORE_CLASSIC_FIREWALL` and `AFTER_CLASSIC_FIREWALL`. (default null or equivalent to `AFTER_CLASSIC_FIREWALL`)"},"network_name":{"description":"The name of the network being created"},"network_profile":{"default":null,"description":"\"A full or partial URL of the network profile to apply to this network.\nThis field can be set only at resource creation time. For example, the\nfollowing are valid URLs:\n * https://www.googleapis.com/compute/beta/projects/{projectId}/global/networkProfiles/{network_profile_name}\n * projects/{projectId}/global/networkProfiles/{network_profile_name}\n"},"project_id":{"description":"The ID of the project where this VPC will be created"},"routes":{"default":[],"description":"List of routes being created in this VPC"},"routing_mode":{"default":"GLOBAL","description":"The network routing mode (default 'GLOBAL')"},"secondary_ranges":{"default":{},"description":"Secondary ranges that will be used in some of the subnets"},"shared_vpc_host":{"default":false,"description":"Makes this project a Shared VPC host if 'true' (default 'false')"},"subnets":{"description":"The list of subnets being created"}}},"version_constraint":"~\u003e 10.0"},"vpn_ha_cb_to_onprem":{"source":"terraform-google-modules/vpn/google//modules/vpn_ha","expressions":{"name":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"network":{"references":["local.peered_network_id"]},"peer_external_gateway":{"references":["var.vpn_configuration.on_prem_public_ip_address0","var.vpn_configuration","var.vpn_configuration.on_prem_public_ip_address1","var.vpn_configuration"]},"project_id":{"references":["var.project_id"]},"region":{"references":["var.private_worker_pool.region","var.private_worker_pool"]},"router_advertise_config":{"references":["local.peered_ip_range"]},"router_asn":{"references":["var.vpn_configuration.router_asn","var.vpn_configuration"]},"tunnels":{"references":["var.vpn_configuration.tunnel0_bgp_peer_address","var.vpn_configuration","var.vpn_configuration.bgp_peer_asn","var.vpn_configuration","var.vpn_configuration.tunnel0_bgp_session_range","var.vpn_configuration","local.psk_secret_data","var.vpn_configuration.tunnel1_bgp_peer_address","var.vpn_configuration","var.vpn_configuration.bgp_peer_asn","var.vpn_configuration","var.vpn_configuration.tunnel1_bgp_session_range","var.vpn_configuration","local.psk_secret_data"]}},"count_expression":{"references":["var.vpn_configuration.enable_vpn","var.vpn_configuration"]},"module":{"outputs":{"external_gateway":{"expression":{"references":["var.peer_external_gateway","google_compute_external_vpn_gateway.external_gateway[0]","google_compute_external_vpn_gateway.external_gateway"]},"description":"External VPN gateway resource."},"gateway":{"expression":{"references":["google_compute_ha_vpn_gateway.ha_gateway"]},"description":"HA VPN gateway resource."},"name":{"expression":{"references":["local.vpn_gateway_self_link"]},"description":"VPN gateway name."},"random_secret":{"sensitive":true,"expression":{"references":["local.secret"]},"description":"Generated secret."},"router":{"expression":{"references":["var.router_name","google_compute_router.router[0]","google_compute_router.router"]},"description":"Router resource (only if auto-created)."},"router_name":{"expression":{"references":["local.router"]},"description":"Router name."},"self_link":{"expression":{"references":["local.vpn_gateway_self_link"]},"description":"HA VPN gateway self link."},"tunnel_names":{"expression":{"references":["var.tunnels","google_compute_vpn_tunnel.tunnels"]},"description":"VPN tunnel names."},"tunnel_self_links":{"sensitive":true,"expression":{"references":["var.tunnels","google_compute_vpn_tunnel.tunnels"]},"description":"VPN tunnel self links."},"tunnels":{"sensitive":true,"expression":{"references":["var.tunnels","google_compute_vpn_tunnel.tunnels"]},"description":"VPN tunnel resources."}},"resources":[{"address":"google_compute_external_vpn_gateway.external_gateway","mode":"managed","type":"google_compute_external_vpn_gateway","name":"external_gateway","provider_config_key":"google","expressions":{"description":{"references":["var.external_vpn_gateway_description"]},"labels":{"references":["var.labels"]},"name":{"references":["var.peer_external_gateway.name","var.peer_external_gateway","var.peer_external_gateway.name","var.peer_external_gateway","var.name"]},"project":{"references":["var.project_id"]},"redundancy_type":{"references":["var.peer_external_gateway.redundancy_type","var.peer_external_gateway"]}},"schema_version":0,"count_expression":{"references":["var.peer_external_gateway"]}},{"address":"google_compute_ha_vpn_gateway.ha_gateway","mode":"managed","type":"google_compute_ha_vpn_gateway","name":"ha_gateway","provider_config_key":"google","expressions":{"name":{"references":["var.name"]},"network":{"references":["var.network"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"stack_type":{"references":["var.stack_type"]}},"schema_version":1,"count_expression":{"references":["var.create_vpn_gateway"]}},{"address":"google_compute_router.router","mode":"managed","type":"google_compute_router","name":"router","provider_config_key":"google","expressions":{"bgp":[{"advertise_mode":{"references":["var.router_advertise_config","var.router_advertise_config.mode","var.router_advertise_config"]},"advertised_groups":{"references":["var.router_advertise_config","var.router_advertise_config.mode","var.router_advertise_config","var.router_advertise_config.groups","var.router_advertise_config"]},"asn":{"references":["var.router_asn"]},"keepalive_interval":{"references":["var.keepalive_interval"]}}],"name":{"references":["var.name"]},"network":{"references":["var.network"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]}},"schema_version":0,"count_expression":{"references":["var.router_name"]}},{"address":"google_compute_router_interface.router_interface","mode":"managed","type":"google_compute_router_interface","name":"router_interface","provider_config_key":"google","expressions":{"ip_range":{"references":["each.value.bgp_session_range","each.value","each.value.bgp_session_range","each.value"]},"name":{"references":["each.value.bgp_session_name","each.value","each.value.bgp_session_name","each.value","var.name","each.key"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"router":{"references":["local.router"]},"vpn_tunnel":{"references":["google_compute_vpn_tunnel.tunnels","each.key"]}},"schema_version":0,"for_each_expression":{"references":["var.tunnels"]}},{"address":"google_compute_router_peer.bgp_peer","mode":"managed","type":"google_compute_router_peer","name":"bgp_peer","provider_config_key":"google","expressions":{"advertise_mode":{"references":["each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.advertise_mode","each.value.bgp_peer_options","each.value"]},"advertised_groups":{"references":["each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.advertise_mode","each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.advertise_groups","each.value.bgp_peer_options","each.value"]},"advertised_route_priority":{"references":["each.value.bgp_peer_options","each.value","var.route_priority","each.value.bgp_peer_options.route_priority","each.value.bgp_peer_options","each.value","var.route_priority","each.value.bgp_peer_options.route_priority","each.value.bgp_peer_options","each.value"]},"interface":{"references":["google_compute_router_interface.router_interface","each.key"]},"ip_address":{"references":["each.value.bgp_peer_options","each.value","each.value.bgp_peer_options.ip_address","each.value.bgp_peer_options","each.value"]},"name":{"references":["each.value.bgp_session_name","each.value","each.value.bgp_session_name","each.value","var.name","each.key"]},"peer_asn":{"references":["each.value.bgp_peer.asn","each.value.bgp_peer","each.value"]},"peer_ip_address":{"references":["each.value.bgp_peer.address","each.value.bgp_peer","each.value"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"router":{"references":["local.router"]}},"schema_version":0,"for_each_expression":{"references":["var.tunnels"]}},{"address":"google_compute_vpn_tunnel.tunnels","mode":"managed","type":"google_compute_vpn_tunnel","name":"tunnels","provider_config_key":"google","expressions":{"ike_version":{"references":["each.value.ike_version","each.value"]},"labels":{"references":["var.labels"]},"name":{"references":["var.name","each.key"]},"peer_external_gateway":{"references":["each.value.peer_external_gateway_self_link","each.value","each.value.peer_external_gateway_self_link","each.value","local.peer_external_gateway"]},"peer_external_gateway_interface":{"references":["each.value.peer_external_gateway_interface","each.value"]},"peer_gcp_gateway":{"references":["var.peer_gcp_gateway"]},"project":{"references":["var.project_id"]},"region":{"references":["var.region"]},"router":{"references":["local.router"]},"shared_secret":{"references":["each.value.shared_secret","each.value","local.secret","each.value.shared_secret","each.value"]},"vpn_gateway":{"references":["local.vpn_gateway_self_link"]},"vpn_gateway_interface":{"references":["each.value.vpn_gateway_interface","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.tunnels"]}},{"address":"random_id.secret","mode":"managed","type":"random_id","name":"secret","provider_config_key":"random","expressions":{"byte_length":{"references":["var.ipsec_secret_length"]}},"schema_version":0}],"variables":{"create_vpn_gateway":{"default":true,"description":"create a VPN gateway"},"external_vpn_gateway_description":{"default":"Terraform managed external VPN gateway","description":"An optional description of external VPN Gateway"},"ipsec_secret_length":{"default":8,"description":"The lnegth the of shared secret for VPN tunnels"},"keepalive_interval":{"default":20,"description":"The interval in seconds between BGP keepalive messages that are sent to the peer."},"labels":{"default":{},"description":"Labels for vpn components"},"name":{"description":"VPN gateway name, and prefix used for dependent resources."},"network":{"description":"VPC used for the gateway and routes."},"peer_external_gateway":{"default":null,"description":"Configuration of an external VPN gateway to which this VPN is connected."},"peer_gcp_gateway":{"default":null,"description":"Self Link URL of the peer side HA GCP VPN gateway to which this VPN tunnel is connected."},"project_id":{"description":"Project where resources will be created."},"region":{"description":"Region used for resources."},"route_priority":{"default":1000,"description":"Route priority, defaults to 1000."},"router_advertise_config":{"default":null,"description":"Router custom advertisement configuration, ip_ranges is a map of address ranges and descriptions."},"router_asn":{"default":64514,"description":"Router ASN used for auto-created router."},"router_name":{"default":"","description":"Name of router, leave blank to create one."},"stack_type":{"default":"IPV4_ONLY","description":"The IP stack type will apply to all the tunnels associated with this VPN gateway."},"tunnels":{"default":{},"description":"VPN tunnel configurations, bgp_peer_options is usually null."},"vpn_gateway_self_link":{"default":null,"description":"self_link of existing VPN gateway to be used for the vpn tunnel. create_vpn_gateway should be set to false"}}},"version_constraint":"~\u003e 4.0"}},"variables":{"private_worker_pool":{"default":{"create_peered_network":true,"disk_size_gb":100,"enable_network_peering":true,"machine_type":"e2-medium","name":"","no_external_ip":true,"peered_network_id":"","peered_network_subnet_ip":"","peering_address":null,"peering_prefix_length":24,"region":"us-central1"},"description":" name: Name of the worker pool. A name with a random suffix is generated if not set.\n region: The private worker pool region. See https://cloud.google.com/build/docs/locations for available locations.\n disk_size_gb: Size of the disk attached to the worker, in GB.\n machine_type: Machine type of a worker.\n no_external_ip: If true, workers are created without any public address, which prevents network egress to public IPs.\n enable_network_peering: Set to true to enable configuration of networking peering for the private worker pool.\n create_peered_network: If true a network will be created to stablish the network peering.\n peered_network_id: The ID of the existing network to configure peering for the private worker pool if create_peered_network false. The project containing the network must have Service Networking API (`servicenetworking.googleapis.com`) enabled.\n peered_network_subnet_ip: The IP range to be used for the subnet that a will created in the peered network if create_peered_network true.\n peering_address: The IP address or beginning of the peering address range. This can be supplied as an input to reserve a specific address or omitted to allow GCP to choose a valid one.\n peering_prefix_length: The prefix length of the IP peering range. If not present, it means the address field is a single IP address.\n"},"project_id":{"description":"ID of the project where the private pool will be created"},"vpc_flow_logs":{"default":{"aggregation_interval":"INTERVAL_5_SEC","filter_expr":"true","flow_sampling":"0.5","metadata":"INCLUDE_ALL_METADATA","metadata_fields":[]},"description":" aggregation_interval: Toggles the aggregation interval for collecting flow logs. Increasing the interval time will reduce the amount of generated flow logs for long lasting connections. Possible values are: INTERVAL_5_SEC, INTERVAL_30_SEC, INTERVAL_1_MIN, INTERVAL_5_MIN, INTERVAL_10_MIN, INTERVAL_15_MIN.\n flow_sampling: Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported. The value of the field must be in [0, 1].\n metadata: Configures whether metadata fields should be added to the reported VPC flow logs. Possible values are: EXCLUDE_ALL_METADATA, INCLUDE_ALL_METADATA, CUSTOM_METADATA.\n metadata_fields: ist of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and \"metadata\" is set to CUSTOM_METADATA.\n filter_expr: Export filter used to define which VPC flow logs should be logged, as as CEL expression. See https://cloud.google.com/vpc/docs/flow-logs#filtering for details on how to format this field.\n"},"vpn_configuration":{"default":{"bgp_peer_asn":64513,"enable_vpn":false,"on_prem_public_ip_address0":"","on_prem_public_ip_address1":"","psk_secret_name":"","psk_secret_project_id":"","router_asn":64515,"tunnel0_bgp_peer_address":"","tunnel0_bgp_session_range":"","tunnel1_bgp_peer_address":"","tunnel1_bgp_session_range":""},"description":" enable_vpn: set to true to create VPN connection to on prem. If true, the following values must be valid.\n on_prem_public_ip_address0: The first public IP address for on prem VPN connection.\n on_prem_public_ip_address1: The second public IP address for on prem VPN connection.\n router_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for cloud routes.\n bgp_peer_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for peer cloud routes.\n shared_secret: The shared secret used in the VPN.\n psk_secret_project_id: The ID of the project that contains the secret from secret manager that holds the VPN pre-shared key.\n psk_secret_name: The name of the secret to retrieve from secret manager that holds the VPN pre-shared key.\n tunnel0_bgp_peer_address: BGP peer address for tunnel 0.\n tunnel0_bgp_session_range: BGP session range for tunnel 0.\n tunnel1_bgp_peer_address: BGP peer address for tunnel 1.\n tunnel1_bgp_session_range: BGP session range for tunnel 1.\n"}}}},"tf_source":{"source":"terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_source","expressions":{"activate_apis":{"constant_value":["serviceusage.googleapis.com","servicenetworking.googleapis.com","compute.googleapis.com","logging.googleapis.com","iam.googleapis.com","admin.googleapis.com","sourcerepo.googleapis.com","workflows.googleapis.com","artifactregistry.googleapis.com","cloudbuild.googleapis.com","cloudscheduler.googleapis.com","bigquery.googleapis.com","cloudresourcemanager.googleapis.com","cloudbilling.googleapis.com","appengine.googleapis.com","storage-api.googleapis.com","billingbudgets.googleapis.com","dns.googleapis.com"]},"billing_account":{"references":["var.billing_account"]},"buckets_force_destroy":{"references":["var.bucket_force_destroy"]},"cloud_source_repos":{"references":["local.base_cloud_source_repos","local.cloud_source_repos"]},"folder_id":{"references":["google_folder.bootstrap.id","google_folder.bootstrap"]},"group_org_admins":{"references":["var.groups.required_groups.group_org_admins","var.groups.required_groups","var.groups"]},"location":{"references":["var.default_region"]},"org_id":{"references":["var.org_id"]},"project_deletion_policy":{"references":["var.project_deletion_policy"]},"project_id":{"references":["var.project_prefix","random_string.suffix.result","random_string.suffix"]},"project_labels":{"constant_value":{"application_name":"cloudbuild-bootstrap","billing_code":"1234","business_code":"shared","env_code":"b","environment":"bootstrap","primary_contact":"example1","secondary_contact":"example2","vpc":"none"}}},"module":{"outputs":{"cloudbuild_project_id":{"expression":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"depends_on":["google_storage_bucket_iam_member.cloudbuild_iam","google_project_iam_member.org_admins_cloudbuild_editor","google_project_iam_member.org_admins_cloudbuild_viewer","google_project_iam_member.org_admins_source_repo_admin"],"description":"Project for CloudBuild and Cloud Source Repositories."},"csr_repos":{"expression":{"references":["google_sourcerepo_repository.gcp_repo"]},"description":"List of Cloud Source Repos created by the module."},"gcs_cloudbuild_default_bucket":{"expression":{"references":["module.cloudbuild_bucket.bucket.name","module.cloudbuild_bucket.bucket","module.cloudbuild_bucket"]},"depends_on":["google_storage_bucket_iam_member.cloudbuild_iam"],"description":"Bucket used to store temporary files in CloudBuild project."}},"resources":[{"address":"google_project_iam_member.org_admins_cloudbuild_editor","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_editor","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"role":{"constant_value":"roles/cloudbuild.builds.editor"}},"schema_version":0},{"address":"google_project_iam_member.org_admins_cloudbuild_viewer","mode":"managed","type":"google_project_iam_member","name":"org_admins_cloudbuild_viewer","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0},{"address":"google_project_iam_member.org_admins_source_repo_admin","mode":"managed","type":"google_project_iam_member","name":"org_admins_source_repo_admin","provider_config_key":"google","expressions":{"member":{"references":["var.group_org_admins"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"role":{"constant_value":"roles/source.admin"}},"schema_version":0,"count_expression":{"references":["var.cloud_source_repos"]}},{"address":"google_sourcerepo_repository.gcp_repo","mode":"managed","type":"google_sourcerepo_repository","name":"gcp_repo","provider_config_key":"google","expressions":{"name":{"references":["each.value"]},"project":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]}},"schema_version":0,"for_each_expression":{"references":["var.cloud_source_repos","var.cloud_source_repos"]}},{"address":"google_storage_bucket_iam_member.cloudbuild_iam","mode":"managed","type":"google_storage_bucket_iam_member","name":"cloudbuild_iam","provider_config_key":"google","expressions":{"bucket":{"references":["module.cloudbuild_bucket.bucket.name","module.cloudbuild_bucket.bucket","module.cloudbuild_bucket"]},"member":{"references":["module.cloudbuild_project.project_number","module.cloudbuild_project"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0}],"module_calls":{"cloudbuild_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"labels":{"references":["var.storage_bucket_labels"]},"location":{"references":["var.location"]},"name":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]},"project_id":{"references":["module.cloudbuild_project.project_id","module.cloudbuild_project"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"},"cloudbuild_project":{"source":"terraform-google-modules/project-factory/google","expressions":{"activate_apis":{"references":["local.activate_apis"]},"auto_create_network":{"references":["var.project_auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"deletion_policy":{"references":["var.project_deletion_policy"]},"disable_services_on_destroy":{"constant_value":false},"folder_id":{"references":["var.folder_id"]},"labels":{"references":["var.project_labels"]},"name":{"references":["local.cloudbuild_project_id"]},"org_id":{"references":["var.org_id"]},"random_project_id":{"references":["local.use_random_suffix"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["module.project-factory.api_s_account","module.project-factory"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["module.project-factory.api_s_account_fmt","module.project-factory"]},"description":"API service account email formatted for terraform use"},"budget_name":{"expression":{"references":["module.budget.name","module.budget"]},"description":"The name of the budget if created"},"domain":{"expression":{"references":["module.gsuite_group.domain","module.gsuite_group"]},"description":"The organization's domain"},"enabled_api_identities":{"expression":{"references":["module.project-factory.enabled_api_identities","module.project-factory"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project-factory.enabled_apis","module.project-factory"]},"description":"Enabled APIs in the project"},"group_email":{"expression":{"references":["module.gsuite_group.email","module.gsuite_group"]},"description":"The email of the G Suite group with group_name"},"project_bucket_self_link":{"expression":{"references":["module.project-factory.project_bucket_self_link","module.project-factory"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["module.project-factory.project_bucket_url","module.project-factory"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project-factory.project_id","module.project-factory"]},"description":"ID of the project"},"project_name":{"expression":{"references":["module.project-factory.project_name","module.project-factory"]},"description":"Name of the project"},"project_number":{"expression":{"references":["module.project-factory.project_number","module.project-factory"]},"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["module.project-factory.service_account_display_name","module.project-factory"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["module.project-factory.service_account_email","module.project-factory"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["module.project-factory.service_account_id","module.project-factory"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["module.project-factory.service_account_name","module.project-factory"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["module.project-factory.service_account_unique_id","module.project-factory"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["module.project-factory.tag_bindings","module.project-factory"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["module.project-factory.usage_report_export_bucket","module.project-factory"]},"description":"GCE usage reports bucket"}},"module_calls":{"budget":{"source":"./modules/budget","expressions":{"alert_pubsub_topic":{"references":["var.budget_alert_pubsub_topic"]},"alert_spend_basis":{"references":["var.budget_alert_spend_basis"]},"alert_spent_percents":{"references":["var.budget_alert_spent_percents"]},"amount":{"references":["var.budget_amount"]},"billing_account":{"references":["var.billing_account"]},"calendar_period":{"references":["var.budget_calendar_period"]},"create_budget":{"references":["var.budget_amount"]},"custom_period_end_date":{"references":["var.budget_custom_period_end_date"]},"custom_period_start_date":{"references":["var.budget_custom_period_start_date"]},"display_name":{"references":["var.budget_display_name","var.budget_display_name"]},"labels":{"references":["var.budget_labels"]},"monitoring_notification_channels":{"references":["var.budget_monitoring_notification_channels"]},"projects":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"name":{"expression":{"references":["google_billing_budget.budget","google_billing_budget.budget[0].name","google_billing_budget.budget[0]","google_billing_budget.budget"]},"description":"Resource name of the budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}.`"}},"resources":[{"address":"google_billing_budget.budget","mode":"managed","type":"google_billing_budget","name":"budget","provider_config_key":"google","expressions":{"amount":[{"specified_amount":[{"units":{"references":["var.amount"]}}]}],"billing_account":{"references":["var.billing_account"]},"budget_filter":[{"calendar_period":{"references":["local.custom_period","var.calendar_period"]},"credit_types_treatment":{"references":["var.credit_types_treatment"]},"labels":{"references":["var.labels"]},"projects":{"references":["local.projects"]},"services":{"references":["local.services"]}}],"display_name":{"references":["local.display_name"]}},"schema_version":1,"count_expression":{"references":["var.create_budget"]}},{"address":"data.google_project.project","mode":"data","type":"google_project","name":"project","provider_config_key":"google","expressions":{"project_id":{"references":["var.projects","count.index"]}},"schema_version":0,"count_expression":{"references":["var.create_budget","var.projects"]},"depends_on":["var.projects"]}],"variables":{"alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"amount":{"description":"The amount to use as the budget"},"billing_account":{"description":"ID of the billing account to set a budget on"},"calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"create_budget":{"default":true,"description":"If the budget should be created"},"credit_types_treatment":{"default":"INCLUDE_ALL_CREDITS","description":"Specifies how credits should be treated when determining spend for threshold calculations"},"custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"projects":{"description":"The project ids to include in this budget. If empty budget will include all projects"},"services":{"default":null,"description":"A list of services ids to be included in the budget. If omitted, all services will be included in the budget. Service ids can be found at https://cloud.google.com/skus/"}}}},"essential_contacts":{"source":"./modules/essential_contacts","expressions":{"essential_contacts":{"references":["var.essential_contacts"]},"language_tag":{"references":["var.language_tag"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"essential_contacts":{"expression":{"references":["google_essential_contacts_contact.contact"]},"description":"Essential Contact resources created"},"project_id":{"expression":{"references":["var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_essential_contacts_contact.contact","mode":"managed","type":"google_essential_contacts_contact","name":"contact","provider_config_key":"google","expressions":{"email":{"references":["each.key"]},"language_tag":{"references":["var.language_tag"]},"notification_category_subscriptions":{"references":["each.value"]},"parent":{"references":["var.project_id"]}},"schema_version":0,"for_each_expression":{"references":["var.essential_contacts"]}}],"variables":{"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"language_tag":{"description":"Language code to be used for essential contacts notifiactions"},"project_id":{"description":"The GCP project you want to send Essential Contacts notifications for"}}}},"gsuite_group":{"source":"./modules/gsuite_group","expressions":{"domain":{"references":["var.domain"]},"name":{"references":["var.group_name"]},"org_id":{"references":["var.org_id"]}},"module":{"outputs":{"domain":{"expression":{"references":["local.domain"]},"description":"The domain of the group's organization."},"email":{"expression":{"references":["local.email"]},"description":"The email address of the group."},"name":{"expression":{"references":["var.name"]},"description":"The username portion of the email address of the group."}},"resources":[{"address":"data.google_organization.org","mode":"data","type":"google_organization","name":"org","provider_config_key":"google","expressions":{"organization":{"references":["var.org_id"]}},"schema_version":0,"count_expression":{"references":["var.domain","var.name"]}}],"variables":{"domain":{"default":"","description":"The domain name"},"name":{"default":"","description":"The name of the group."},"org_id":{"default":null,"description":"The organization ID."}}}},"project-factory":{"source":"./modules/core_project_factory","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["var.activate_apis"]},"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"bucket_force_destroy":{"references":["var.bucket_force_destroy"]},"bucket_labels":{"references":["var.bucket_labels"]},"bucket_location":{"references":["var.bucket_location"]},"bucket_name":{"references":["var.bucket_name"]},"bucket_pap":{"references":["var.bucket_pap"]},"bucket_project":{"references":["var.bucket_project"]},"bucket_ula":{"references":["var.bucket_ula"]},"bucket_versioning":{"references":["var.bucket_versioning"]},"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"create_project_sa":{"references":["var.create_project_sa"]},"default_network_tier":{"references":["var.default_network_tier"]},"default_service_account":{"references":["var.default_service_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"enable_shared_vpc_host_project":{"references":["var.enable_shared_vpc_host_project"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"folder_id":{"references":["var.folder_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"group_email":{"references":["module.gsuite_group.email","module.gsuite_group"]},"group_role":{"references":["var.group_role"]},"labels":{"references":["var.labels"]},"lien":{"references":["var.lien"]},"manage_group":{"references":["var.group_name"]},"name":{"references":["var.name"]},"org_id":{"references":["var.folder_id","var.org_id"]},"project_id":{"references":["var.project_id"]},"project_sa_name":{"references":["var.project_sa_name"]},"random_project_id":{"references":["var.random_project_id"]},"random_project_id_length":{"references":["var.random_project_id_length"]},"sa_role":{"references":["var.sa_role"]},"shared_vpc":{"references":["var.svpc_host_project_id"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]},"tag_binding_values":{"references":["var.tag_binding_values"]},"usage_bucket_name":{"references":["var.usage_bucket_name"]},"usage_bucket_prefix":{"references":["var.usage_bucket_prefix"]},"vpc_service_control_attach_dry_run":{"references":["var.vpc_service_control_attach_dry_run"]},"vpc_service_control_attach_enabled":{"references":["var.vpc_service_control_attach_enabled"]},"vpc_service_control_perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"vpc_service_control_sleep_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"module":{"outputs":{"api_s_account":{"expression":{"references":["local.api_s_account"]},"description":"API service account email"},"api_s_account_fmt":{"expression":{"references":["local.api_s_account_fmt"]},"description":"API service account email formatted for terraform use"},"enabled_api_identities":{"expression":{"references":["module.project_services.enabled_api_identities","module.project_services"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["module.project_services.enabled_apis","module.project_services"]},"description":"Enabled APIs in the project"},"project_bucket_name":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"The name of the projec's bucket"},"project_bucket_self_link":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket selfLink"},"project_bucket_url":{"expression":{"references":["google_storage_bucket.project_bucket"]},"description":"Project's bucket url"},"project_id":{"expression":{"references":["module.project_services.project_id","module.project_services"]},"depends_on":["module.project_services","google_project.main","google_compute_shared_vpc_service_project.shared_vpc_attachment","google_compute_shared_vpc_host_project.shared_vpc_host"],"description":"ID of the project"},"project_name":{"expression":{"references":["google_project.main.name","google_project.main"]},"description":"Name of the project"},"project_number":{"expression":{"references":["google_project.main.number","google_project.main"]},"depends_on":["module.project_services"],"description":"Numeric identifier for the project"},"service_account_display_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].display_name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The display name of the default service account"},"service_account_email":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The email of the default service account"},"service_account_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].account_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The id of the default service account"},"service_account_name":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].name","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The fully-qualified name of the default service account"},"service_account_unique_id":{"expression":{"references":["var.create_project_sa","google_service_account.default_service_account[0].unique_id","google_service_account.default_service_account[0]","google_service_account.default_service_account"]},"description":"The unique id of the default service account"},"tag_bindings":{"expression":{"references":["google_tags_tag_binding.bindings"]},"description":"Tag bindings"},"usage_report_export_bucket":{"expression":{"references":["google_project_usage_export_bucket.usage_report_export[0]","google_project_usage_export_bucket.usage_report_export"]},"description":"GCE usage reports bucket"}},"resources":[{"address":"google_access_context_manager_service_perimeter_dry_run_resource.service_perimeter_attachment_dry_run","mode":"managed","type":"google_access_context_manager_service_perimeter_dry_run_resource","name":"service_perimeter_attachment_dry_run","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_dry_run","var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_access_context_manager_service_perimeter_resource.service_perimeter_attachment","mode":"managed","type":"google_access_context_manager_service_perimeter_resource","name":"service_perimeter_attachment","provider_config_key":"google","expressions":{"perimeter_name":{"references":["var.vpc_service_control_perimeter_name"]},"resource":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled"]},"depends_on":["google_service_account.default_service_account"]},{"address":"google_compute_project_cloud_armor_tier.cloud_armor_tier_config","mode":"managed","type":"google_compute_project_cloud_armor_tier","name":"cloud_armor_tier_config","provider_config_key":"google","expressions":{"cloud_armor_tier":{"references":["var.cloud_armor_tier"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.cloud_armor_tier"]}},{"address":"google_compute_project_default_network_tier.default","mode":"managed","type":"google_compute_project_default_network_tier","name":"default","provider_config_key":"google","expressions":{"network_tier":{"references":["var.default_network_tier"]},"project":{"references":["google_project.main.number","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.default_network_tier"]}},{"address":"google_compute_shared_vpc_host_project.shared_vpc_host","mode":"managed","type":"google_compute_shared_vpc_host_project","name":"shared_vpc_host","provider_config_key":"google-beta","expressions":{"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_host_project"]},"depends_on":["module.project_services"]},{"address":"google_compute_shared_vpc_service_project.shared_vpc_attachment","mode":"managed","type":"google_compute_shared_vpc_service_project","name":"shared_vpc_attachment","provider_config_key":"google-beta","expressions":{"host_project":{"references":["var.shared_vpc"]},"service_project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.enable_shared_vpc_service_project"]},"depends_on":["time_sleep.wait_5_seconds[0]","module.project_services"]},{"address":"google_compute_subnetwork_iam_member.apis_service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"apis_service_account_role_to_vpc_subnets","provider_config_key":"google-beta","expressions":{"member":{"references":["local.api_s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.shared_vpc_subnets"]},"depends_on":["module.project_services"]},{"address":"google_compute_subnetwork_iam_member.group_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"group_role_to_vpc_subnets","provider_config_key":"google-beta","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.manage_group","var.shared_vpc_subnets"]}},{"address":"google_compute_subnetwork_iam_member.service_account_role_to_vpc_subnets","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_account_role_to_vpc_subnets","provider_config_key":"google-beta","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["var.shared_vpc"]},"region":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["var.shared_vpc_subnets","count.index","var.shared_vpc_subnets","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","var.create_project_sa","var.shared_vpc_subnets"]}},{"address":"google_project.main","mode":"managed","type":"google_project","name":"main","provider_config_key":"google","expressions":{"auto_create_network":{"references":["var.auto_create_network"]},"billing_account":{"references":["var.billing_account"]},"deletion_policy":{"references":["var.deletion_policy"]},"folder_id":{"references":["local.project_folder_id"]},"labels":{"references":["var.labels"]},"name":{"references":["var.name"]},"org_id":{"references":["local.project_org_id"]},"project_id":{"references":["local.temp_project_id"]}},"schema_version":1},{"address":"google_project_default_service_accounts.default_service_accounts","mode":"managed","type":"google_project_default_service_accounts","name":"default_service_accounts","provider_config_key":"google","expressions":{"action":{"references":["var.default_service_account"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"restore_policy":{"constant_value":"REVERT_AND_IGNORE_FAILURE"}},"schema_version":0,"count_expression":{"references":["var.default_service_account"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.controlling_group_vpc_membership","mode":"managed","type":"google_project_iam_member","name":"controlling_group_vpc_membership","provider_config_key":"google","expressions":{"member":{"references":["local.shared_vpc_users","count.index"]},"project":{"references":["var.shared_vpc"]},"role":{"constant_value":"roles/compute.networkUser"}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","var.enable_shared_vpc_service_project","var.shared_vpc_subnets","local.shared_vpc_users_length"]},"depends_on":["module.project_services"]},{"address":"google_project_iam_member.default_service_account_membership","mode":"managed","type":"google_project_iam_member","name":"default_service_account_membership","provider_config_key":"google","expressions":{"member":{"references":["local.s_account_fmt"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.sa_role"]}},"schema_version":0,"count_expression":{"references":["var.sa_role","var.create_project_sa"]}},{"address":"google_project_iam_member.gsuite_group_role","mode":"managed","type":"google_project_iam_member","name":"gsuite_group_role","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"project":{"references":["google_project.main.project_id","google_project.main"]},"role":{"references":["var.group_role"]}},"schema_version":0,"count_expression":{"references":["var.manage_group"]}},{"address":"google_project_service.enable_access_context_manager","mode":"managed","type":"google_project_service","name":"enable_access_context_manager","provider_config_key":"google","expressions":{"project":{"references":["google_project.main.number","google_project.main"]},"service":{"constant_value":"accesscontextmanager.googleapis.com"}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]}},{"address":"google_project_usage_export_bucket.usage_report_export","mode":"managed","type":"google_project_usage_export_bucket","name":"usage_report_export","provider_config_key":"google","expressions":{"bucket_name":{"references":["var.usage_bucket_name"]},"prefix":{"references":["var.usage_bucket_prefix","var.usage_bucket_prefix","google_project.main.project_id","google_project.main"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.usage_bucket_name"]},"depends_on":["module.project_services"]},{"address":"google_resource_manager_lien.lien","mode":"managed","type":"google_resource_manager_lien","name":"lien","provider_config_key":"google","expressions":{"origin":{"constant_value":"project-factory"},"parent":{"references":["google_project.main.number","google_project.main"]},"reason":{"constant_value":"Project Factory lien"},"restrictions":{"constant_value":["resourcemanager.projects.delete"]}},"schema_version":0,"count_expression":{"references":["var.lien"]}},{"address":"google_service_account.default_service_account","mode":"managed","type":"google_service_account","name":"default_service_account","provider_config_key":"google","expressions":{"account_id":{"references":["var.project_sa_name"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["var.name"]},"project":{"references":["google_project.main.project_id","google_project.main"]}},"schema_version":0,"count_expression":{"references":["var.create_project_sa"]}},{"address":"google_service_account_iam_member.service_account_grant_to_group","mode":"managed","type":"google_service_account_iam_member","name":"service_account_grant_to_group","provider_config_key":"google","expressions":{"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/iam.serviceAccountUser"},"service_account_id":{"references":["google_project.main.project_id","google_project.main","google_service_account.default_service_account[0].email","google_service_account.default_service_account[0]","google_service_account.default_service_account"]}},"schema_version":0,"count_expression":{"references":["var.manage_group","var.create_project_sa"]}},{"address":"google_storage_bucket.project_bucket","mode":"managed","type":"google_storage_bucket","name":"project_bucket","provider_config_key":"google-beta","expressions":{"force_destroy":{"references":["var.bucket_force_destroy"]},"labels":{"references":["var.bucket_labels"]},"location":{"references":["var.bucket_location"]},"name":{"references":["local.project_bucket_name"]},"project":{"references":["var.bucket_project","local.base_project_id","google_project.main.project_id","google_project.main","var.bucket_project"]},"public_access_prevention":{"references":["var.bucket_pap"]},"uniform_bucket_level_access":{"references":["var.bucket_ula"]},"versioning":[{"enabled":{"references":["var.bucket_versioning"]}}]},"schema_version":3,"count_expression":{"references":["local.create_bucket"]}},{"address":"google_storage_bucket_iam_member.api_s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"api_s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.api_s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket"]},"depends_on":["module.project_services"]},{"address":"google_storage_bucket_iam_member.group_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"group_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.group_id"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.manage_group"]}},{"address":"google_storage_bucket_iam_member.s_account_storage_admin_on_project_bucket","mode":"managed","type":"google_storage_bucket_iam_member","name":"s_account_storage_admin_on_project_bucket","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.project_bucket[0].name","google_storage_bucket.project_bucket[0]","google_storage_bucket.project_bucket"]},"member":{"references":["local.s_account_fmt"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0,"count_expression":{"references":["local.create_bucket","var.create_project_sa"]}},{"address":"google_tags_tag_binding.bindings","mode":"managed","type":"google_tags_tag_binding","name":"bindings","provider_config_key":"google","expressions":{"parent":{"references":["google_project.main.number","google_project.main"]},"tag_value":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.tag_binding_values"]}},{"address":"random_id.random_project_id_suffix","mode":"managed","type":"random_id","name":"random_project_id_suffix","provider_config_key":"module.tf_source.module.cloudbuild_project.module.project-factory:random","expressions":{"byte_length":{"constant_value":2}},"schema_version":0},{"address":"random_string.random_project_id_suffix","mode":"managed","type":"random_string","name":"random_project_id_suffix","provider_config_key":"module.tf_source.module.cloudbuild_project.module.project-factory:random","expressions":{"length":{"references":["var.random_project_id_length"]},"special":{"constant_value":false},"upper":{"constant_value":false}},"schema_version":2,"count_expression":{"references":["local.use_random_string"]}},{"address":"time_sleep.wait_5_seconds","mode":"managed","type":"time_sleep","name":"wait_5_seconds","provider_config_key":"module.tf_source.module.cloudbuild_project.module.project-factory:time","expressions":{"create_duration":{"references":["var.vpc_service_control_sleep_duration"]}},"schema_version":0,"count_expression":{"references":["var.vpc_service_control_attach_enabled","var.vpc_service_control_attach_dry_run"]},"depends_on":["google_access_context_manager_service_perimeter_resource.service_perimeter_attachment[0]","google_project_service.enable_access_context_manager[0]"]}],"module_calls":{"project_services":{"source":"../project_services","expressions":{"activate_api_identities":{"references":["var.activate_api_identities"]},"activate_apis":{"references":["local.activate_apis"]},"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_services_on_destroy":{"references":["var.disable_services_on_destroy"]},"project_id":{"references":["google_project.main.project_id","google_project.main"]}},"module":{"outputs":{"enabled_api_identities":{"expression":{"references":["google_project_service_identity.project_service_identities"]},"description":"Enabled API identities in the project"},"enabled_apis":{"expression":{"references":["google_project_service.project_services"]},"description":"Enabled APIs in the project"},"project_id":{"expression":{"references":["google_project_service.project_services","var.project_id"]},"description":"The GCP project you want to enable APIs on"}},"resources":[{"address":"google_project_iam_member.project_service_identity_roles","mode":"managed","type":"google_project_iam_member","name":"project_service_identity_roles","provider_config_key":"google","expressions":{"member":{"references":["each.value.email","each.value"]},"project":{"references":["var.project_id"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.add_service_roles"]}},{"address":"google_project_service.project_services","mode":"managed","type":"google_project_service","name":"project_services","provider_config_key":"google","expressions":{"disable_dependent_services":{"references":["var.disable_dependent_services"]},"disable_on_destroy":{"references":["var.disable_services_on_destroy"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.services"]}},{"address":"google_project_service_identity.project_service_identities","mode":"managed","type":"google_project_service_identity","name":"project_service_identities","provider_config_key":"google-beta","expressions":{"project":{"references":["var.project_id"]},"service":{"references":["each.value.api","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.activate_api_identities"]}},{"address":"data.google_compute_default_service_account.default","mode":"data","type":"google_compute_default_service_account","name":"default","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["local.activate_compute_identity"]}}],"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":[],"description":"The list of apis to activate within the project"},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_dependent_services"},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_on_destroy"},"enable_apis":{"default":true,"description":"Whether to actually enable the APIs. If false, this module is a no-op."},"project_id":{"description":"The GCP project you want to enable APIs on"}}}}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`. Use for services supported by `gcloud beta services identity create`\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false."},"enable_shared_vpc_service_project":{"description":"If this project should be attached to a shared VPC. If true, you must set shared_vpc variable."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"group_email":{"default":"","description":"The email address of a group to control the project by being assigned group_role."},"group_role":{"default":"","description":"The role to give the controlling group (group_name) over the project."},"labels":{"default":{},"description":"Map of labels for project"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"manage_group":{"default":false,"description":"A toggle to indicate if a G Suite group should be managed."},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}}},"quotas":{"source":"./modules/quota_manager","expressions":{"consumer_quotas":{"references":["var.consumer_quotas"]},"project_id":{"references":["module.project-factory.project_id","module.project-factory"]}},"module":{"outputs":{"quota_overrides":{"expression":{"references":["google_service_usage_consumer_quota_override.override"]},"description":"The server-generated names of the quota override."}},"resources":[{"address":"google_service_usage_consumer_quota_override.override","mode":"managed","type":"google_service_usage_consumer_quota_override","name":"override","provider_config_key":"google-beta","expressions":{"dimensions":{"references":["each.value.dimensions","each.value"]},"force":{"constant_value":true},"limit":{"references":["each.value.limit","each.value"]},"metric":{"references":["each.value.metric","each.value"]},"override_value":{"references":["each.value.value","each.value"]},"project":{"references":["var.project_id"]},"service":{"references":["each.value.service","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.consumer_quotas"]}}],"variables":{"consumer_quotas":{"description":"The quotas configuration you want to override for the project."},"project_id":{"description":"The GCP project where you want to manage the consumer quotas"}}}},"shared_vpc_access":{"source":"./modules/shared_vpc_access","expressions":{"active_apis":{"references":["var.activate_apis","var.activate_api_identities"]},"enable_shared_vpc_service_project":{"references":["var.svpc_host_project_id"]},"grant_network_role":{"references":["var.grant_network_role"]},"grant_services_security_admin_role":{"references":["var.grant_services_security_admin_role"]},"host_project_id":{"references":["var.svpc_host_project_id"]},"lookup_project_numbers":{"constant_value":false},"service_project_id":{"references":["module.project-factory.project_id","module.project-factory"]},"service_project_number":{"references":["module.project-factory.project_number","module.project-factory"]},"shared_vpc_subnets":{"references":["var.shared_vpc_subnets"]}},"module":{"outputs":{"active_api_service_accounts":{"expression":{"references":["local.active_apis"]},"description":"List of active API service accounts in the service project."},"project_id":{"expression":{"references":["var.service_project_id"]},"depends_on":["google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","google_project_iam_member.gke_host_agent","google_project_iam_member.service_shared_vpc_user"],"description":"Service project ID."}},"resources":[{"address":"google_compute_subnetwork_iam_member.cloudservices_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"cloudservices_shared_vpc_subnet_users","provider_config_key":"google-beta","expressions":{"member":{"references":["local.service_project_number"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"constant_value":"roles/compute.networkUser"},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role","local.subnetwork_api"]}},{"address":"google_compute_subnetwork_iam_member.service_shared_vpc_subnet_users","mode":"managed","type":"google_compute_subnetwork_iam_member","name":"service_shared_vpc_subnet_users","provider_config_key":"google-beta","expressions":{"member":{"references":["local.apis","local.subnetwork_api","count.index"]},"project":{"references":["var.host_project_id"]},"region":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]},"role":{"references":["local.apis","local.subnetwork_api","count.index"]},"subnetwork":{"references":["local.subnetwork_api","count.index","local.subnetwork_api","count.index"]}},"schema_version":0,"count_expression":{"references":["var.grant_network_role","local.subnetwork_api"]}},{"address":"google_project_iam_member.composer_host_agent","mode":"managed","type":"google_project_iam_member","name":"composer_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"composer.googleapis.com\"].service_account","local.apis[\"composer.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/composer.sharedVpcAgent"}},"schema_version":0,"count_expression":{"references":["local.composer_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datasfusion_network_viewer","mode":"managed","type":"google_project_iam_member","name":"datasfusion_network_viewer","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datafusion.googleapis.com\"].service_account","local.apis[\"datafusion.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkViewer"}},"schema_version":0,"count_expression":{"references":["local.datafusion_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.datastream_network_admin","mode":"managed","type":"google_project_iam_member","name":"datastream_network_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"datastream.googleapis.com\"].service_account","local.apis[\"datastream.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.networkAdmin"}},"schema_version":0,"count_expression":{"references":["local.datastream_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_network_admin_role"]}},{"address":"google_project_iam_member.gke_host_agent","mode":"managed","type":"google_project_iam_member","name":"gke_host_agent","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/container.hostServiceAgentUser"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_network_role"]}},{"address":"google_project_iam_member.gke_security_admin","mode":"managed","type":"google_project_iam_member","name":"gke_security_admin","provider_config_key":"google","expressions":{"member":{"references":["local.apis[\"container.googleapis.com\"].service_account","local.apis[\"container.googleapis.com\"]","local.apis"]},"project":{"references":["var.host_project_id"]},"role":{"constant_value":"roles/compute.securityAdmin"}},"schema_version":0,"count_expression":{"references":["local.gke_shared_vpc_enabled","var.enable_shared_vpc_service_project","var.grant_services_security_admin_role"]}},{"address":"google_project_iam_member.service_shared_vpc_user","mode":"managed","type":"google_project_iam_member","name":"service_shared_vpc_user","provider_config_key":"google","expressions":{"member":{"references":["local.apis","each.value"]},"project":{"references":["var.host_project_id"]},"role":{"references":["local.apis","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.shared_vpc_subnets","var.enable_shared_vpc_service_project","var.grant_network_role","local.active_apis"]}},{"address":"data.google_project.service_project","mode":"data","type":"google_project","name":"service_project","provider_config_key":"google","expressions":{"project_id":{"references":["var.service_project_id"]}},"schema_version":0,"count_expression":{"references":["var.lookup_project_numbers"]}}],"variables":{"active_apis":{"default":[],"description":"The list of active apis on the service project. If api is not active this module will not try to activate it"},"enable_shared_vpc_service_project":{"description":"Flag set if SVPC enabled"},"grant_network_role":{"default":true,"description":"Whether or not to grant service agents the network roles on the host project"},"grant_services_network_admin_role":{"default":false,"description":"Whether or not to grant Datastream Service acount the Network Admin role on the host project so it can manage firewall rules"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"host_project_id":{"description":"The ID of the host project which hosts the shared VPC"},"lookup_project_numbers":{"default":true,"description":"Whether to look up the project numbers from data sources. If false, `service_project_number` will be used instead."},"service_project_id":{"description":"The ID of the service project"},"service_project_number":{"default":null,"description":"Project number of the service project. Will be used if `lookup_service_project_number` is false."},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"}}},"depends_on":["module.project-factory.enabled_apis"]}},"variables":{"activate_api_identities":{"default":[],"description":" The list of service identities (Google Managed service account for the API) to force-create for the project (e.g. in order to grant additional roles).\n APIs in this list will automatically be appended to `activate_apis`.\n Not including the API in this list will follow the default behaviour for identity creation (which is usually when the first resource using the API is created).\n Any roles (e.g. service agent role) must be explicitly listed. See https://cloud.google.com/iam/docs/understanding-roles#service-agent-roles-roles for a list of related roles.\n"},"activate_apis":{"default":["compute.googleapis.com"],"description":"The list of apis to activate within the project"},"auto_create_network":{"default":false,"description":"Create the default network"},"billing_account":{"description":"The ID of the billing account to associate this project with"},"bucket_force_destroy":{"default":false,"description":"Force the deletion of all objects within the GCS bucket when deleting the bucket (optional)"},"bucket_labels":{"default":{},"description":" A map of key/value label pairs to assign to the bucket (optional)"},"bucket_location":{"default":"US","description":"The location for a GCS bucket to create (optional)"},"bucket_name":{"default":"","description":"A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)"},"bucket_pap":{"default":"inherited","description":"Enable Public Access Prevention. Possible values are \"enforced\" or \"inherited\"."},"bucket_project":{"default":"","description":"A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)"},"bucket_ula":{"default":true,"description":"Enable Uniform Bucket Level Access"},"bucket_versioning":{"default":false,"description":"Enable versioning for a GCS bucket to create (optional)"},"budget_alert_pubsub_topic":{"default":null,"description":"The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`"},"budget_alert_spend_basis":{"default":"CURRENT_SPEND","description":"The type of basis used to determine if spend has passed the threshold"},"budget_alert_spent_percents":{"default":[0.5,0.7,1],"description":"A list of percentages of the budget to alert on when threshold is exceeded"},"budget_amount":{"default":null,"description":"The amount to use for a budget alert"},"budget_calendar_period":{"default":null,"description":"Specifies the calendar period for the budget. Possible values are MONTH, QUARTER, YEAR, CALENDAR_PERIOD_UNSPECIFIED, CUSTOM. custom_period_start_date and custom_period_end_date must be set if CUSTOM"},"budget_custom_period_end_date":{"default":null,"description":"Specifies the end date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_custom_period_start_date":{"default":null,"description":"Specifies the start date (DD-MM-YYYY) for the calendar_period CUSTOM"},"budget_display_name":{"default":null,"description":"The display name of the budget. If not set defaults to `Budget For \u003cprojects[0]|All Projects\u003e` "},"budget_labels":{"default":{},"description":"A single label and value pair specifying that usage from only this set of labeled resources should be included in the budget."},"budget_monitoring_notification_channels":{"default":[],"description":"A list of monitoring notification channels in the form `[projects/{project_id}/notificationChannels/{channel_id}]`. A maximum of 5 channels are allowed."},"cloud_armor_tier":{"default":null,"description":"Managed protection tier to be set. Possible values are: CA_STANDARD, CA_ENTERPRISE_PAYGO"},"consumer_quotas":{"default":[],"description":"The quotas configuration you want to override for the project."},"create_project_sa":{"default":true,"description":"Whether the default service account for the project shall be created"},"default_network_tier":{"default":"","description":"Default Network Service Tier for resources created in this project. If unset, the value will not be modified. See https://cloud.google.com/network-tiers/docs/using-network-service-tiers and https://cloud.google.com/network-tiers."},"default_service_account":{"default":"disable","description":"Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`."},"deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project."},"disable_dependent_services":{"default":true,"description":"Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed."},"disable_services_on_destroy":{"default":true,"description":"Whether project services will be disabled when the resources are destroyed"},"domain":{"default":"","description":"The domain name (optional)."},"enable_shared_vpc_host_project":{"default":false,"description":"If this project is a shared VPC host project. If true, you must *not* set svpc_host_project_id variable. Default is false."},"essential_contacts":{"default":{},"description":"A mapping of users or groups to be assigned as Essential Contacts to the project, specifying a notification category"},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"grant_network_role":{"default":true,"description":"Whether or not to grant networkUser role on the host project/subnets"},"grant_services_security_admin_role":{"default":false,"description":"Whether or not to grant Kubernetes Engine Service Agent the Security Admin role on the host project so it can manage firewall rules"},"group_name":{"default":"","description":"A group to control the project by being assigned group_role (defaults to project editor)"},"group_role":{"default":"roles/editor","description":"The role to give the controlling group (group_name) over the project (defaults to project editor)"},"labels":{"default":{},"description":"Map of labels for project"},"language_tag":{"default":"en-US","description":"Language code to be used for essential contacts notifications"},"lien":{"default":false,"description":"Add a lien on the project to prevent accidental deletion"},"name":{"description":"The name for the project"},"org_id":{"default":null,"description":"The organization ID."},"project_id":{"default":"","description":"The ID to give the project. If not provided, the `name` will be used."},"project_sa_name":{"default":"project-service-account","description":"Default service account name for the project."},"random_project_id":{"default":false,"description":"Adds a suffix of 4 random characters to the `project_id`."},"random_project_id_length":{"default":null,"description":"Sets the length of `random_project_id` to the provided length, and uses a `random_string` for a larger collusion domain. Recommended for use with CI."},"sa_role":{"default":"","description":"A role to give the default Service Account for the project (defaults to none)"},"shared_vpc_subnets":{"default":[],"description":"List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)"},"svpc_host_project_id":{"default":"","description":"The ID of the host project which hosts the shared VPC"},"tag_binding_values":{"default":[],"description":"Tag values to bind the project to."},"usage_bucket_name":{"default":"","description":"Name of a GCS bucket to store GCE usage reports in (optional)"},"usage_bucket_prefix":{"default":"","description":"Prefix in the GCS bucket to store GCE usage reports in (optional)"},"vpc_service_control_attach_dry_run":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in Dry Run Mode. vpc_service_control_attach_enabled should be false for this to be true"},"vpc_service_control_attach_enabled":{"default":false,"description":"Whether the project will be attached to a VPC Service Control Perimeter in ENFORCED MODE. vpc_service_control_attach_dry_run should be false for this to be true"},"vpc_service_control_perimeter_name":{"default":null,"description":"The name of a VPC Service Control Perimeter to add the created project to"},"vpc_service_control_sleep_duration":{"default":"5s","description":"The duration to sleep in seconds before adding the project to a shared VPC after the project is added to the VPC Service Control Perimeter. VPC-SC is eventually consistent."}}},"version_constraint":"~\u003e 18.0"}},"variables":{"activate_apis":{"default":["serviceusage.googleapis.com","servicenetworking.googleapis.com","compute.googleapis.com","logging.googleapis.com","iam.googleapis.com","admin.googleapis.com"],"description":"List of APIs to enable in the Cloudbuild project."},"billing_account":{"description":"The ID of the billing account to associate projects with."},"buckets_force_destroy":{"default":false,"description":"When deleting CloudBuild buckets, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"cloud_source_repos":{"default":["gcp-policies","gcp-org","gcp-envs","gcp-networks","gcp-projects"],"description":"List of Cloud Source Repos to create with CloudBuild triggers."},"folder_id":{"default":"","description":"The ID of a folder to host this project"},"group_org_admins":{"description":"Google Group for GCP Organization Administrators"},"location":{"default":"us-central1","description":"Location for build artifacts bucket"},"org_id":{"description":"GCP Organization ID"},"project_auto_create_network":{"default":false,"description":"Create the default network for the project created."},"project_deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project created."},"project_id":{"default":"","description":"Custom project ID to use for project created."},"project_labels":{"default":{},"description":"Labels to apply to the project."},"storage_bucket_labels":{"default":{},"description":"Labels to apply to the storage bucket."}}},"version_constraint":"~\u003e 11.0","depends_on":["module.seed_bootstrap"]},"tf_workspace":{"source":"terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace","expressions":{"artifacts_bucket_name":{"references":["var.bucket_prefix","module.tf_source.cloudbuild_project_id","module.tf_source","local.cb_config","each.key"]},"buckets_force_destroy":{"references":["var.bucket_force_destroy"]},"cloudbuild_apply_filename":{"constant_value":"cloudbuild-tf-apply.yaml"},"cloudbuild_plan_filename":{"constant_value":"cloudbuild-tf-plan.yaml"},"cloudbuild_sa":{"references":["google_service_account.terraform-env-sa","each.key"]},"create_cloudbuild_sa":{"constant_value":false},"create_state_bucket":{"constant_value":false},"diff_sa_project":{"constant_value":true},"enable_worker_pool":{"constant_value":true},"location":{"references":["var.default_region"]},"log_bucket_name":{"references":["var.bucket_prefix","module.tf_source.cloudbuild_project_id","module.tf_source","local.cb_config","each.key"]},"project_id":{"references":["module.tf_source.cloudbuild_project_id","module.tf_source"]},"state_bucket_self_link":{"references":["local.cb_config","each.key"]},"substitutions":{"references":["var.org_id","var.billing_account","var.default_region","module.tf_source.cloudbuild_project_id","module.tf_source","local.gar_repository","local.docker_tag_version_terraform"]},"tf_apply_branches":{"constant_value":["development","nonproduction","production"]},"tf_repo_uri":{"references":["module.tf_source.csr_repos","module.tf_source","local.cb_config","each.key"]},"trigger_location":{"references":["var.default_region"]},"worker_pool_id":{"references":["module.tf_private_pool.private_worker_pool_id","module.tf_private_pool"]}},"for_each_expression":{"references":["local.granular_sa"]},"module":{"outputs":{"artifacts_bucket":{"expression":{"references":["module.artifacts_bucket.bucket.self_link","module.artifacts_bucket.bucket","module.artifacts_bucket"]},"description":"Bucket for storing TF plans"},"cloudbuild_apply_trigger_id":{"expression":{"references":["google_cloudbuild_trigger.triggers[\"apply\"].id","google_cloudbuild_trigger.triggers[\"apply\"]","google_cloudbuild_trigger.triggers"]},"description":"Trigger used for running TF apply"},"cloudbuild_plan_trigger_id":{"expression":{"references":["google_cloudbuild_trigger.triggers[\"plan\"].id","google_cloudbuild_trigger.triggers[\"plan\"]","google_cloudbuild_trigger.triggers"]},"description":"Trigger used for running TF plan"},"cloudbuild_sa":{"expression":{"references":["local.cloudbuild_sa"]},"description":"SA used by Cloud Build triggers"},"logs_bucket":{"expression":{"references":["module.log_bucket.bucket.self_link","module.log_bucket.bucket","module.log_bucket"]},"description":"Bucket for storing TF logs"},"state_bucket":{"expression":{"references":["local.state_bucket_self_link"]},"description":"Bucket for storing TF state"}},"resources":[{"address":"google_cloudbuild_trigger.triggers","mode":"managed","type":"google_cloudbuild_trigger","name":"triggers","provider_config_key":"google","expressions":{"description":{"references":["each.key","local.repo_uri_description","var.tf_repo_dir"]},"filename":{"references":["local.default_triggers_explicit","each.key"]},"ignored_files":{"references":["var.cloudbuild_ignored_files"]},"included_files":{"references":["var.cloudbuild_included_files"]},"location":{"references":["var.trigger_location"]},"name":{"references":["local.default_prefix","each.key"]},"project":{"references":["var.project_id"]},"service_account":{"references":["local.cloudbuild_sa"]},"substitutions":{"references":["local.default_subst","var.substitutions"]}},"schema_version":2,"for_each_expression":{"references":["local.default_triggers_steps"]},"depends_on":["google_project_iam_member.cb_sa_roles"]},{"address":"google_project_iam_member.cb_sa_logging","mode":"managed","type":"google_project_iam_member","name":"cb_sa_logging","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["var.project_id"]},"role":{"constant_value":"roles/logging.logWriter"}},"schema_version":0},{"address":"google_project_iam_member.cb_sa_roles","mode":"managed","type":"google_project_iam_member","name":"cb_sa_roles","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["each.value.project_id","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["local.cb_sa_roles_expand"]}},{"address":"google_project_iam_member.pool_user","mode":"managed","type":"google_project_iam_member","name":"pool_user","provider_config_key":"google","expressions":{"member":{"references":["data.google_project.cloudbuild_project[0].number","data.google_project.cloudbuild_project[0]","data.google_project.cloudbuild_project"]},"project":{"references":["local.worker_pool_project"]},"role":{"constant_value":"roles/cloudbuild.workerPoolUser"}},"schema_version":0,"count_expression":{"references":["var.enable_worker_pool"]}},{"address":"google_service_account.cb_sa","mode":"managed","type":"google_service_account","name":"cb_sa","provider_config_key":"google","expressions":{"account_id":{"references":["var.create_cloudbuild_sa_name","var.create_cloudbuild_sa_name","local.default_prefix"]},"create_ignore_already_exists":{"constant_value":true},"display_name":{"references":["local.default_prefix"]},"project":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.create_cloudbuild_sa"]}},{"address":"google_service_account_iam_member.cb_sa_self","mode":"managed","type":"google_service_account_iam_member","name":"cb_sa_self","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"role":{"references":["each.value"]},"service_account_id":{"references":["local.cloudbuild_sa"]}},"schema_version":0,"for_each_expression":{"references":["var.diff_sa_project"]}},{"address":"google_service_account_iam_member.cb_service_agent_impersonate","mode":"managed","type":"google_service_account_iam_member","name":"cb_service_agent_impersonate","provider_config_key":"google","expressions":{"member":{"references":["data.google_project.cloudbuild_project[0].number","data.google_project.cloudbuild_project[0]","data.google_project.cloudbuild_project"]},"role":{"constant_value":"roles/iam.serviceAccountTokenCreator"},"service_account_id":{"references":["local.cloudbuild_sa"]}},"schema_version":0,"count_expression":{"references":["var.diff_sa_project"]}},{"address":"google_sourcerepo_repository_iam_member.member","mode":"managed","type":"google_sourcerepo_repository_iam_member","name":"member","provider_config_key":"google","expressions":{"member":{"references":["local.cloudbuild_sa_email"]},"project":{"references":["local.source_repo_project"]},"repository":{"references":["local.source_repo_name"]},"role":{"constant_value":"roles/viewer"}},"schema_version":0,"count_expression":{"references":["local.is_source_repo"]}},{"address":"google_storage_bucket_iam_member.artifacts_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"artifacts_admin","provider_config_key":"google","expressions":{"bucket":{"references":["module.artifacts_bucket.bucket.self_link","module.artifacts_bucket.bucket","module.artifacts_bucket"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"google_storage_bucket_iam_member.log_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"log_admin","provider_config_key":"google","expressions":{"bucket":{"references":["module.log_bucket.bucket.self_link","module.log_bucket.bucket","module.log_bucket"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"google_storage_bucket_iam_member.state_admin","mode":"managed","type":"google_storage_bucket_iam_member","name":"state_admin","provider_config_key":"google","expressions":{"bucket":{"references":["local.state_bucket_self_link"]},"member":{"references":["local.cloudbuild_sa_email"]},"role":{"constant_value":"roles/storage.admin"}},"schema_version":0},{"address":"data.google_project.cloudbuild_project","mode":"data","type":"google_project","name":"cloudbuild_project","provider_config_key":"google","expressions":{"project_id":{"references":["var.project_id"]}},"schema_version":0,"count_expression":{"references":["var.diff_sa_project"]}}],"module_calls":{"artifacts_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"location":{"references":["var.location"]},"name":{"references":["var.artifacts_bucket_name","var.artifacts_bucket_name","local.default_prefix","var.project_id"]},"project_id":{"references":["var.project_id"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"},"log_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"location":{"references":["var.location"]},"name":{"references":["var.log_bucket_name","var.log_bucket_name","local.default_prefix","var.project_id"]},"project_id":{"references":["var.project_id"]}},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"},"state_bucket":{"source":"terraform-google-modules/cloud-storage/google//modules/simple_bucket","expressions":{"force_destroy":{"references":["var.buckets_force_destroy"]},"location":{"references":["var.location"]},"name":{"references":["var.create_state_bucket_name","var.create_state_bucket_name","local.default_prefix","var.project_id"]},"project_id":{"references":["var.project_id"]}},"count_expression":{"references":["var.create_state_bucket"]},"module":{"outputs":{"apphub_service_uri":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket","google_storage_bucket.bucket.name","google_storage_bucket.bucket","var.location"]},"description":"URI in CAIS style to be used by Apphub."},"bucket":{"expression":{"references":["google_storage_bucket.bucket"]},"description":"The created storage bucket"},"internal_kms_configuration":{"expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config","module.encryption_key[0]","module.encryption_key"]},"description":"The intenal KMS Resource."},"name":{"expression":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"description":"Bucket name."},"url":{"expression":{"references":["google_storage_bucket.bucket.url","google_storage_bucket.bucket"]},"description":"Bucket URL."}},"resources":[{"address":"google_storage_bucket.bucket","mode":"managed","type":"google_storage_bucket","name":"bucket","provider_config_key":"google","expressions":{"autoclass":[{"enabled":{"references":["var.autoclass"]}}],"force_destroy":{"references":["var.force_destroy"]},"labels":{"references":["var.labels"]},"location":{"references":["var.location"]},"name":{"references":["var.name"]},"project":{"references":["var.project_id"]},"public_access_prevention":{"references":["var.public_access_prevention"]},"storage_class":{"references":["var.storage_class"]},"uniform_bucket_level_access":{"references":["var.bucket_policy_only"]},"versioning":[{"enabled":{"references":["var.versioning"]}}]},"schema_version":3},{"address":"google_storage_bucket_iam_member.members","mode":"managed","type":"google_storage_bucket_iam_member","name":"members","provider_config_key":"google","expressions":{"bucket":{"references":["google_storage_bucket.bucket.name","google_storage_bucket.bucket"]},"member":{"references":["each.value.member","each.value"]},"role":{"references":["each.value.role","each.value"]}},"schema_version":0,"for_each_expression":{"references":["var.iam_members"]}},{"address":"data.google_storage_project_service_account.gcs_account","mode":"data","type":"google_storage_project_service_account","name":"gcs_account","provider_config_key":"google","expressions":{"project":{"references":["var.project_id"]}},"schema_version":0}],"module_calls":{"encryption_key":{"source":"terraform-google-modules/kms/google","expressions":{"decrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"encrypters":{"references":["data.google_storage_project_service_account.gcs_account.email_address","data.google_storage_project_service_account.gcs_account"]},"key_destroy_scheduled_duration":{"references":["var.internal_encryption_config.key_destroy_scheduled_duration","var.internal_encryption_config"]},"key_rotation_period":{"references":["var.internal_encryption_config.key_rotation_period","var.internal_encryption_config"]},"keyring":{"references":["var.name"]},"keys":{"references":["var.name"]},"location":{"references":["var.location"]},"prevent_destroy":{"references":["var.internal_encryption_config.prevent_destroy","var.internal_encryption_config"]},"project_id":{"references":["var.project_id"]},"set_decrypters_for":{"references":["var.name"]},"set_encrypters_for":{"references":["var.name"]}},"count_expression":{"references":["var.internal_encryption_config.create_encryption_key","var.internal_encryption_config"]},"module":{"outputs":{"keyring":{"expression":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Self link of the keyring."},"keyring_name":{"expression":{"references":["google_kms_key_ring.key_ring.name","google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Name of the keyring."},"keyring_resource":{"expression":{"references":["google_kms_key_ring.key_ring"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Keyring resource."},"keys":{"expression":{"references":["local.keys_by_name"]},"depends_on":["google_kms_crypto_key_iam_binding.owners","google_kms_crypto_key_iam_binding.decrypters","google_kms_crypto_key_iam_binding.encrypters"],"description":"Map of key name =\u003e key self link."}},"resources":[{"address":"google_kms_crypto_key.key","mode":"managed","type":"google_kms_crypto_key","name":"key","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key.key_ephemeral","mode":"managed","type":"google_kms_crypto_key","name":"key_ephemeral","provider_config_key":"google","expressions":{"crypto_key_backend":{"references":["var.crypto_key_backend"]},"destroy_scheduled_duration":{"references":["var.key_destroy_scheduled_duration"]},"import_only":{"references":["var.import_only"]},"key_ring":{"references":["google_kms_key_ring.key_ring.id","google_kms_key_ring.key_ring"]},"labels":{"references":["var.labels"]},"name":{"references":["var.keys","count.index"]},"purpose":{"references":["var.purpose"]},"rotation_period":{"references":["var.key_rotation_period"]},"skip_initial_version_creation":{"references":["var.skip_initial_version_creation"]},"version_template":[{"algorithm":{"references":["var.key_algorithm"]},"protection_level":{"references":["var.key_protection_level"]}}]},"schema_version":1,"count_expression":{"references":["var.prevent_destroy","var.keys"]}},{"address":"google_kms_crypto_key_iam_binding.decrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"decrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_decrypters_for","count.index"]},"members":{"references":["var.decrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyDecrypter"}},"schema_version":0,"count_expression":{"references":["var.set_decrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.encrypters","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"encrypters","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_encrypters_for","count.index"]},"members":{"references":["var.encrypters","count.index"]},"role":{"constant_value":"roles/cloudkms.cryptoKeyEncrypter"}},"schema_version":0,"count_expression":{"references":["var.set_encrypters_for"]}},{"address":"google_kms_crypto_key_iam_binding.owners","mode":"managed","type":"google_kms_crypto_key_iam_binding","name":"owners","provider_config_key":"google","expressions":{"crypto_key_id":{"references":["local.keys_by_name","var.set_owners_for","count.index"]},"members":{"references":["var.owners","count.index"]},"role":{"constant_value":"roles/owner"}},"schema_version":0,"count_expression":{"references":["var.set_owners_for"]}},{"address":"google_kms_key_ring.key_ring","mode":"managed","type":"google_kms_key_ring","name":"key_ring","provider_config_key":"google","expressions":{"location":{"references":["var.location"]},"name":{"references":["var.keyring"]},"project":{"references":["var.project_id"]}},"schema_version":0}],"variables":{"crypto_key_backend":{"default":null,"description":"(Optional) The resource name of the backend environment associated with all CryptoKeyVersions within this CryptoKey. The resource name is in the format 'projects//locations//ekmConnections/*' and only applies to 'EXTERNAL_VPC' keys."},"decrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_decrypters_for."},"encrypters":{"default":[],"description":"List of comma-separated owners for each key declared in set_encrypters_for."},"import_only":{"default":false,"description":"Whether these keys may contain imported versions only."},"key_algorithm":{"default":"GOOGLE_SYMMETRIC_ENCRYPTION","description":"The algorithm to use when creating a version based on this template. See the https://cloud.google.com/kms/docs/reference/rest/v1/CryptoKeyVersionAlgorithm for possible inputs."},"key_destroy_scheduled_duration":{"default":null,"description":"Set the period of time that versions of keys spend in the DESTROY_SCHEDULED state before transitioning to DESTROYED."},"key_protection_level":{"default":"SOFTWARE","description":"The protection level to use when creating a version based on this template. Default value: \"SOFTWARE\" Possible values: [\"SOFTWARE\", \"HSM\", \"EXTERNAL\", \"EXTERNAL_VPC\"]"},"key_rotation_period":{"default":"7776000s","description":"Generate a new key every time this period passes."},"keyring":{"description":"Keyring name."},"keys":{"default":[],"description":"Key names."},"labels":{"default":{},"description":"Labels, provided as a map"},"location":{"description":"Location for the keyring."},"owners":{"default":[],"description":"List of comma-separated owners for each key declared in set_owners_for."},"prevent_destroy":{"default":true,"description":"Set the prevent_destroy lifecycle attribute on keys."},"project_id":{"description":"Project id where the keyring will be created."},"purpose":{"default":"ENCRYPT_DECRYPT","description":"The immutable purpose of the CryptoKey. Default value is ENCRYPT_DECRYPT. See purpose reference (https://cloud.google.com/kms/docs/reference/rest/v1/projects.locations.keyRings.cryptoKeys#CryptoKeyPurpose) for possible inputs."},"set_decrypters_for":{"default":[],"description":"Name of keys for which decrypters will be set."},"set_encrypters_for":{"default":[],"description":"Name of keys for which encrypters will be set."},"set_owners_for":{"default":[],"description":"Name of keys for which owners will be set."},"skip_initial_version_creation":{"default":false,"description":"If set to true, the request will create CryptoKeys without any CryptoKeyVersions."}}},"version_constraint":"~\u003e 3.0"}},"variables":{"autoclass":{"default":false,"description":"While set to true, autoclass is enabled for this bucket."},"bucket_policy_only":{"default":true,"description":"Enables Bucket Policy Only access to a bucket."},"cors":{"default":[],"description":"Configuration of CORS for bucket with structure as defined in https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/storage_bucket#cors."},"custom_placement_config":{"default":null,"description":"Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null."},"encryption":{"default":null,"description":"A Cloud KMS key that will be used to encrypt objects inserted into this bucket. The key name should follow the format of `projects/\u003cproject-name\u003e/locations/\u003clocation-name\u003e/keyRings/\u003ckeyring-name\u003e/cryptoKeys/\u003ckey-name\u003e`. To use a Cloud KMS key automatically created by this module use the `internal_encryption_config` input variable."},"force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"iam_members":{"default":[],"description":"The list of IAM members to grant permissions on the bucket."},"internal_encryption_config":{"default":{"create_encryption_key":false,"key_destroy_scheduled_duration":null,"key_rotation_period":"7776000s","prevent_destroy":false},"description":" Configuration for the creation of an internal Google Cloud Key Management Service (KMS) Key for use as Customer-managed encryption key (CMEK) for the GCS Bucket\n instead of creating one in advance and providing the key in the variable `encryption.default_kms_key_name`.\n create_encryption_key: If `true` a Google Cloud Key Management Service (KMS) KeyRing and a Key will be created\n prevent_destroy: Set the prevent_destroy lifecycle attribute on keys.\n key_destroy_scheduled_duration: Set the period of time that versions of keys spend in the `DESTROY_SCHEDULED` state before transitioning to `DESTROYED`.\n key_rotation_period: Generate a new key every time this period passes.\n"},"labels":{"default":null,"description":"A set of key/value label pairs to assign to the bucket."},"lifecycle_rules":{"default":[],"description":"The bucket's Lifecycle Rules configuration."},"location":{"description":"The location of the bucket. See https://cloud.google.com/storage/docs/locations."},"log_bucket":{"default":null,"description":"The bucket that will receive log objects."},"log_object_prefix":{"default":null,"description":"The object prefix for log objects. If it's not provided, by default GCS sets this to this bucket's name"},"name":{"description":"The name of the bucket."},"project_id":{"description":"The ID of the project to create the bucket in."},"public_access_prevention":{"default":"inherited","description":"Prevents public access to a bucket. Acceptable values are inherited or enforced. If inherited, the bucket uses public access prevention, only if the bucket is subject to the public access prevention organization policy constraint."},"retention_policy":{"default":null,"description":"Configuration of the bucket's data retention policy for how long objects in the bucket should be retained."},"soft_delete_policy":{"default":{"retention_duration_seconds":null},"description":"Soft delete policies to apply. Format is the same as described in provider documentation https://www.terraform.io/docs/providers/google/r/storage_bucket.html#nested_soft_delete_policy"},"storage_class":{"default":null,"description":"The Storage Class of the new bucket."},"versioning":{"default":true,"description":"While set to true, versioning is fully enabled for this bucket."},"website":{"default":{},"description":"Map of website values. Supported attributes: main_page_suffix, not_found_page"}}},"version_constraint":"~\u003e 9.0"}},"variables":{"artifacts_bucket_name":{"default":"","description":"Custom bucket name for Cloud Build artifacts."},"buckets_force_destroy":{"default":false,"description":"When deleting the bucket for storing CloudBuild logs/TF state, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"cloudbuild_apply_filename":{"default":null,"description":"Optional Cloud Build YAML definition used for terraform apply. Defaults to using inline definition."},"cloudbuild_env_vars":{"default":[],"description":"Optional list of environment variables to be used in builds. List of strings of form KEY=VALUE expected."},"cloudbuild_ignored_files":{"default":[],"description":"Optional list. Changes only affecting ignored files will not invoke a build."},"cloudbuild_included_files":{"default":[],"description":"Optional list. Changes affecting at least one of these files will invoke a build."},"cloudbuild_plan_filename":{"default":null,"description":"Optional Cloud Build YAML definition used for terraform plan. Defaults to using inline definition."},"cloudbuild_sa":{"default":"","description":"Custom SA id of form projects/{{project}}/serviceAccounts/{{email}} to be used by the CloudBuild trigger. Defaults to being created if empty."},"cloudbuild_sa_roles":{"default":{},"description":"Optional to assign to custom CloudBuild SA. Map of project name or any static key to object with project_id and list of roles."},"create_cloudbuild_sa":{"default":true,"description":"Create a Service Account for use in Cloud Build. If false `cloudbuild_sa` has to be specified."},"create_cloudbuild_sa_name":{"default":"","description":"Custom name to be used in the creation of the Cloud Build service account if `create_cloudbuild_sa` is true. Defaults to generated name if empty"},"create_state_bucket":{"default":true,"description":"Create a GCS bucket for storing state. If false `state_bucket_self_link` has to be specified."},"create_state_bucket_name":{"default":"","description":"Custom bucket name for storing TF state. Used if `create_state_bucket` is true. Defaults to generated name if empty."},"diff_sa_project":{"default":false,"description":"Set to true if `cloudbuild_sa` is in a different project for setting up https://cloud.google.com/build/docs/securing-builds/configure-user-specified-service-accounts#cross-project_set_up."},"enable_worker_pool":{"default":false,"description":"Set to true to use a private worker pool in the Cloud Build Trigger."},"location":{"default":"us-central1","description":"Location for build logs/state bucket"},"log_bucket_name":{"default":"","description":"Custom bucket name for Cloud Build logs."},"prefix":{"default":"","description":"Prefix of the state/log buckets and triggers planning/applying config. If unset computes a prefix from tf_repo_uri and tf_repo_dir variables."},"project_id":{"description":"GCP project for Cloud Build triggers, state and log buckets."},"state_bucket_self_link":{"default":"","description":"Custom GCS bucket for storing TF state. Defaults to being created if empty."},"substitutions":{"default":{},"description":"Map of substitutions to use in builds."},"tf_apply_branches":{"default":["main"],"description":"List of git branches configured to run terraform apply Cloud Build trigger. All other branches will run plan by default."},"tf_cloudbuilder":{"default":"hashicorp/terraform:1.3.10","description":"Name of the Cloud Builder image used for running build steps."},"tf_repo_dir":{"default":"","description":"The directory inside the repo where the Terrafrom root config is located. If empty defaults to repo root."},"tf_repo_type":{"default":"CLOUD_SOURCE_REPOSITORIES","description":"Type of repo. When the repo type is CLOUDBUILD_V2_REPOSITORY, it will use the generic Cloudbuild 2nd gen Repository API."},"tf_repo_uri":{"default":"","description":"The URI of the repo where Terraform configs are stored. If using Cloud Build Repositories (2nd Gen) this is the repository ID where the Dockerfile is stored. Repository ID Format is 'projects/{{project}}/locations/{{location}}/connections/{{parent_connection}}/repositories/{{name}}'."},"trigger_location":{"description":"Location of for Cloud Build triggers created in the workspace. If using private pools should be the same location as the pool."},"worker_pool_id":{"default":"","description":"Custom private worker pool ID. Format: 'projects/PROJECT_ID/locations/REGION/workerPools/PRIVATE_POOL_ID'."}}},"version_constraint":"~\u003e 11.0","depends_on":["module.tf_source","module.tf_cloud_builder"]}},"variables":{"attribute_condition":{"default":null,"description":"Workload Identity Pool Provider attribute condition expression. [More info](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/iam_workload_identity_pool_provider#attribute_condition)"},"billing_account":{"description":"The ID of the billing account to associate projects with."},"bucket_force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete all contained objects. If false, Terraform will fail to delete buckets which contain objects."},"bucket_prefix":{"default":"bkt","description":"Name prefix to use for state bucket created."},"bucket_tfstate_kms_force_destroy":{"default":false,"description":"When deleting a bucket, this boolean option will delete the KMS keys used for the Terraform state bucket."},"default_region":{"default":"us-central1","description":"Default region to create resources where applicable."},"default_region_2":{"default":"us-west1","description":"Secondary default region to create resources where applicable."},"default_region_gcs":{"default":"US","description":"Case-Sensitive default region to create gcs resources where applicable."},"default_region_kms":{"default":"us","description":"Secondary default region to create kms resources where applicable."},"folder_deletion_protection":{"default":"true","description":"Prevent Terraform from destroying or recreating the folder."},"folder_prefix":{"default":"fldr","description":"Name prefix to use for folders created. Should be the same in all steps."},"groups":{"description":"Contain the details of the Groups to be created."},"initial_group_config":{"default":"WITH_INITIAL_OWNER","description":"Define the group configuration when it is initialized. Valid values are: WITH_INITIAL_OWNER, EMPTY and INITIAL_GROUP_CONFIG_UNSPECIFIED."},"org_id":{"description":"GCP Organization ID"},"org_policy_admin_role":{"default":false,"description":"Additional Org Policy Admin role for admin group. You can use this for testing purposes."},"parent_folder":{"default":"","description":"Optional - for an organization with existing projects or for development/validation. It will place all the example foundation resources under the provided folder instead of the root organization. The value is the numeric folder ID. The folder must already exist."},"project_deletion_policy":{"default":"PREVENT","description":"The deletion policy for the project created."},"project_prefix":{"default":"prj","description":"Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters."},"workflow_deletion_protection":{"default":true,"description":"Whether Terraform will be prevented from destroying a workflow. When the field is set to true or unset in Terraform state, a `terraform apply` or `terraform destroy` that would delete the workflow will fail. When the field is set to false, deleting the workflow is allowed."}}}},"relevant_attributes":[{"resource":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.random_id.random_project_id_suffix","attribute":["hex"]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace.module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service_identity.project_service_identities","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_cloud_builder.google_service_account.workflow_sa[0]","attribute":["email"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","attribute":["number"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","attribute":["number"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.gsuite_group.data.google_organization.org","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["email"]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace.module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.gcp_projects_state_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","attribute":["project_id"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["name"]},{"resource":"module.tf_source.module.cloudbuild_project.module.budget.google_billing_budget.budget","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["unique_id"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.shared_vpc_access.data.google_project.service_project[0]","attribute":["number"]},{"resource":"random_string.suffix","attribute":["result"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.random_string.random_project_id_suffix[0]","attribute":["result"]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"google_folder.bootstrap","attribute":["name"]},{"resource":"module.seed_bootstrap.google_service_account.org_terraform[0]","attribute":["email"]},{"resource":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.seed_bootstrap.google_folder_iam_member.tmp_project_creator[0]","attribute":["etag"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["name"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","attribute":["trigger_id"]},{"resource":"module.bootstrap_csr_repo.null_resource.run_destroy_command","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace.module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["email"]},{"resource":"module.seed_bootstrap.module.seed_project.module.quotas.google_service_usage_consumer_quota_override.override","attribute":[]},{"resource":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_cloud_builder.google_workflows_workflow.builder","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.build_terraform_image.null_resource.gcloud_auth_google_credentials","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["display_name"]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace.module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.gsuite_group.data.google_organization.org","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.random_id.random_project_id_suffix","attribute":["hex"]},{"resource":"module.build_terraform_image.null_resource.run_command","attribute":[]},{"resource":"google_folder.bootstrap","attribute":["id"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service_identity.project_service_identities","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.google_compute_instance.vm-proxy","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.bootstrap_csr_repo.data.external.env_override[0]","attribute":["result","download"]},{"resource":"module.tf_cloud_builder.google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.budget.data.google_project.project","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_shared_vpc_host_project.shared_vpc_host[0]","attribute":["project"]},{"resource":"module.tf_workspace[\"env\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.bootstrap_csr_repo.null_resource.gcloud_auth_google_credentials","attribute":[]},{"resource":"module.bootstrap_csr_repo.null_resource.run_command","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.random_string.random_project_id_suffix[0]","attribute":["result"]},{"resource":"module.bootstrap_csr_repo.null_resource.additional_components","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["name"]},{"resource":"google_service_account.terraform-env-sa[\"proj\"]","attribute":["email"]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace.module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.google_compute_router.cb-router","attribute":["region"]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","attribute":["name"]},{"resource":"module.tf_source.module.cloudbuild_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"org\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.quotas.google_service_usage_consumer_quota_override.override","attribute":[]},{"resource":"data.google_project.cloudbuild_project","attribute":["number"]},{"resource":"module.tf_workspace.module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_tags_tag_binding.bindings","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace.module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_cloud_builder.google_cloudbuild_trigger.build_trigger","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace.google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.seed_bootstrap.google_storage_bucket.org_terraform_state","attribute":["name"]},{"resource":"module.tf_private_pool.google_compute_router.cb-router","attribute":["name"]},{"resource":"module.gcp_projects_state_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["unique_id"]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace.module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.budget.google_billing_budget.budget[0]","attribute":["name"]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","attribute":[]},{"resource":"module.required_group.google_cloud_identity_group.group","attribute":["name"]},{"resource":"module.seed_bootstrap.random_id.suffix","attribute":["hex"]},{"resource":"google_service_account.terraform-env-sa[\"org\"]","attribute":["email"]},{"resource":"module.tf_source.module.cloudbuild_project.module.budget.google_billing_budget.budget[0]","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.required_group.google_cloud_identity_group.group","attribute":["group_key",0,"id"]},{"resource":"module.gcp_projects_state_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["name"]},{"resource":"google_service_account.terraform-env-sa[\"net\"]","attribute":["email"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.subnets.google_compute_subnetwork.subnetwork","attribute":[]},{"resource":"module.bootstrap_csr_repo.random_id.cache[0]","attribute":["hex"]},{"resource":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"net\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.seed_bootstrap.google_organization_iam_member.tmp_project_creator[0]","attribute":["org_id"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.firewall_rules.google_compute_firewall.rules","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.optional_group.google_cloud_identity_group.group","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.state_bucket[0].module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","attribute":["location"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["display_name"]},{"resource":"module.build_terraform_image.random_id.cache[0]","attribute":["hex"]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"bootstrap\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.optional_group.google_cloud_identity_group.group","attribute":["group_key",0,"id"]},{"resource":"module.tf_workspace.module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_tags_tag_binding.bindings","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["account_id"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.firewall_rules.google_compute_firewall.rules_ingress_egress","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_shared_vpc_host_project.shared_vpc_host","attribute":[]},{"resource":"module.tf_private_pool.google_cloudbuild_worker_pool.private_pool","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.essential_contacts.google_essential_contacts_contact.contact","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"google_service_account.terraform-env-sa[\"env\"]","attribute":["email"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"bootstrap\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_workspace.module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_project.main","attribute":["name"]},{"resource":"module.tf_private_pool.random_string.suffix","attribute":["result"]},{"resource":"module.build_terraform_image.null_resource.run_destroy_command","attribute":[]},{"resource":"module.tf_cloud_builder.module.bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace.google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.build_terraform_image.null_resource.additional_components","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.shared_vpc_access.data.google_project.service_project[0]","attribute":["number"]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.routes.google_compute_route.route","attribute":[]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["address"]},{"resource":"module.seed_bootstrap.module.seed_project.module.budget.google_billing_budget.budget","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["self_link"]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":["project"]},{"resource":"module.tf_private_pool.module.firewall_rules[0].google_compute_firewall.rules_ingress_egress","attribute":[]},{"resource":"data.google_project.seed_project","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_storage_bucket.project_bucket","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_project.module.budget.data.google_project.project","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_source.google_sourcerepo_repository.gcp_repo","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"proj\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"proj\"].data.google_project.cloudbuild_project[0]","attribute":["number"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","attribute":["name"]},{"resource":"module.seed_bootstrap.google_service_account.org_terraform[0]","attribute":["name"]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.tf_cloud_builder.google_cloud_scheduler_job.trigger_workflow","attribute":["id"]},{"resource":"module.tf_workspace.google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.google_project.main","attribute":["project_id"]},{"resource":"module.tf_cloud_builder.google_artifact_registry_repository.tf-image-repo","attribute":["name"]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"bootstrap\"].google_cloudbuild_trigger.triggers[\"apply\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"net\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_workspace[\"env\"].module.artifacts_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"env\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"google_service_account.terraform-env-sa[\"bootstrap\"]","attribute":["email"]},{"resource":"module.tf_source.module.cloudbuild_project.module.project-factory.module.project_services.google_project_service.project_services","attribute":[]},{"resource":"module.tf_workspace[\"net\"].module.log_bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"org\"].module.log_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.log_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace.module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_private_pool.module.peered_network[0].module.vpc.google_compute_network.network","attribute":[]},{"resource":"time_sleep.cloud_builder","attribute":[]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_cloud_builder.module.bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.gcp_projects_state_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"google_service_account.terraform-env-sa","attribute":[]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.bootstrap_csr_repo.null_resource.gcloud_auth_service_account_key_file","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_private_pool.google_compute_global_address.worker_pool_range[0]","attribute":["prefix_length"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_service_account.default_service_account[0]","attribute":["account_id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.google_storage_bucket.project_bucket","attribute":[]},{"resource":"module.seed_bootstrap.data.google_storage_project_service_account.gcs_account","attribute":["email_address"]},{"resource":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","attribute":["url"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.tf_workspace[\"proj\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key_ephemeral","attribute":[]},{"resource":"module.build_terraform_image.null_resource.gcloud_auth_service_account_key_file","attribute":[]},{"resource":"module.seed_bootstrap.module.seed_project.module.project-factory.module.project_services.google_project_service.project_services","attribute":[]},{"resource":"module.tf_workspace[\"net\"].google_cloudbuild_trigger.triggers[\"plan\"]","attribute":["id"]},{"resource":"module.tf_workspace[\"org\"].google_service_account.cb_sa[0]","attribute":["id"]},{"resource":"module.tf_workspace.module.artifacts_bucket.google_storage_bucket.bucket","attribute":[]},{"resource":"module.seed_bootstrap.module.kms[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_cloud_builder.module.bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_cloud_builder.module.bucket.google_storage_bucket.bucket","attribute":["name"]},{"resource":"module.tf_workspace[\"org\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.module.encryption_key[0].google_kms_crypto_key.key","attribute":[]},{"resource":"module.tf_workspace[\"bootstrap\"].module.artifacts_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.tf_private_pool.google_service_networking_connection.worker_pool_conn[0]","attribute":["peering"]},{"resource":"module.tf_workspace[\"net\"].module.state_bucket[0].google_storage_bucket.bucket","attribute":[]},{"resource":"module.tf_source.module.cloudbuild_bucket.module.encryption_key[0].google_kms_key_ring.key_ring","attribute":["id"]},{"resource":"module.seed_bootstrap.module.seed_project.module.essential_contacts.google_essential_contacts_contact.contact","attribute":[]},{"resource":"module.build_terraform_image.data.external.env_override[0]","attribute":["result","download"]},{"resource":"module.tf_workspace[\"env\"].module.state_bucket[0].module.encryption_key[0].google_kms_crypto_key.key","attribute":[]}],"timestamp":"2025-08-06T13:00:27Z"} diff --git a/0-bootstrap/bootstrap.tfplan b/0-bootstrap/bootstrap.tfplan deleted file mode 100644 index 39180199f33a3760a602d84d10e7f19d22271220..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 281042 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�?S>tyjyNC2o_ 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 z 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 diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index a73ed130f..0d8bb8751 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -185,6 +185,7 @@ locals { "prj-org-secrets", "prj-org-interconnect", "prj-org-scc", + "prj-net-hub-svpc", "prj-net-p-svpc", "prj-net-d-svpc", "prj-net-n-svpc", @@ -196,7 +197,6 @@ locals { "prj-org-secrets", "prj-org-interconnect", "prj-org-scc", - "prj-net-hub-svpc", "prj-net-p-svpc", "prj-net-d-svpc", "prj-net-n-svpc", From 04cb167b713e8074ed92e32ed7fa06becfaa34d9 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 14:20:58 -0300 Subject: [PATCH 036/114] fix lint --- 1-org/README.md | 6 ++--- 1-org/envs/shared/service_control.tf | 4 ++-- 3-networks-svpc/envs/development/main.tf | 28 ++++++++++++------------ 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/1-org/README.md b/1-org/README.md index e9484bbdf..469aa1d35 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -174,7 +174,7 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f ``` 2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: - + ``` { from = { @@ -298,7 +298,7 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu ``` 2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: - + ``` { from = { @@ -324,7 +324,7 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu }, ``` -1. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. +3. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 0d8bb8751..690d3e761 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -208,9 +208,9 @@ locals { ) ingress_policies_keys_dry_run = ["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"] - egress_policies_keys_dry_run = ["seed_to_cicd", "org_sa_to_scc", "user_to_seed"] + egress_policies_keys_dry_run = ["seed_to_cicd", "org_sa_to_scc"] ingress_policies_keys = ["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"] - egress_policies_keys = ["seed_to_cicd", "org_sa_to_scc", "user_to_seed"] + egress_policies_keys = ["seed_to_cicd", "org_sa_to_scc"] ingress_policies_dry_run_map = zipmap( local.ingress_policies_keys_dry_run, diff --git a/3-networks-svpc/envs/development/main.tf b/3-networks-svpc/envs/development/main.tf index 6264d8c16..6eaa2899f 100644 --- a/3-networks-svpc/envs/development/main.tf +++ b/3-networks-svpc/envs/development/main.tf @@ -46,18 +46,18 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.6" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + access_context_manager_policy_id = var.access_context_manager_policy_id + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.6" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } From ddb47b51cac548b2abb2ec657462c6d4015fde9d Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 16:07:52 -0300 Subject: [PATCH 037/114] rm backend.tf file --- 0-bootstrap/backend.tf | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 0-bootstrap/backend.tf diff --git a/0-bootstrap/backend.tf b/0-bootstrap/backend.tf deleted file mode 100644 index d68aaa77f..000000000 --- a/0-bootstrap/backend.tf +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2021 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. - */ - -terraform { - backend "gcs" { - bucket = "bkt-prj-b-seed-tfstate-9e2b" - prefix = "terraform/bootstrap/state" - } -} From 3b3b7bf3010e5eb4a05c4ca3c60e3dae3e7eb6a7 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 16:14:32 -0300 Subject: [PATCH 038/114] add terraform.example.tfvars --- 0-bootstrap/terraform.example.tfvars | 171 +++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 0-bootstrap/terraform.example.tfvars diff --git a/0-bootstrap/terraform.example.tfvars b/0-bootstrap/terraform.example.tfvars new file mode 100644 index 000000000..1efeefaa9 --- /dev/null +++ b/0-bootstrap/terraform.example.tfvars @@ -0,0 +1,171 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +org_id = "REPLACE_ME" # format "000000000000" + +billing_account = "REPLACE_ME" # format "000000-000000-000000" + +// For enabling the automatic groups creation, uncoment the +// variables and update the values with the group names +groups = { + # create_required_groups = false # Change to true to create the required_groups + # create_optional_groups = false # Change to true to create the optional_groups + # billing_project = "REPLACE_ME" # Fill to create required or optional groups + required_groups = { + group_org_admins = "REPLACE_ME" # example "gcp-organization-admins@example.com" + group_billing_admins = "REPLACE_ME" # example "gcp-billing-admins@example.com" + billing_data_users = "REPLACE_ME" # example "gcp-billing-data@example.com" + audit_data_users = "REPLACE_ME" # example "gcp-audit-data@example.com" + } + # optional_groups = { + # gcp_security_reviewer = "" #"gcp_security_reviewer_local_test@example.com" + # gcp_network_viewer = "" #"gcp_network_viewer_local_test@example.com" + # gcp_scc_admin = "" #"gcp_scc_admin_local_test@example.com" + # gcp_global_secrets_admin = "" #"gcp_global_secrets_admin_local_test@example.com" + # gcp_kms_admin = "" #"gcp_kms_admin_local_test@example.com" + # } +} + +default_region = "us-central1" +default_region_2 = "us-west1" +default_region_gcs = "US" +default_region_kms = "us" + +# Optional - for an organization with existing projects or for development/validation. +# Uncomment this variable to place all the example foundation resources under +# the provided folder instead of the root organization. +# The variable value is the numeric folder ID +# The folder must already exist. +# parent_folder = "01234567890" + + +/* ---------------------------------------- + Specific to github_bootstrap + ---------------------------------------- */ +# Un-comment github_bootstrap and its outputs if you want to use GitHub Actions instead of Cloud Build +# gh_repos = { +# owner = "YOUR-GITHUB-USER-OR-ORGANIZATION", +# bootstrap = "YOUR-BOOTSTRAP-REPOSITORY", +# organization = "YOUR-ORGANIZATION-REPOSITORY", +# environments = "YOUR-ENVIRONMENTS-REPOSITORY", +# networks = "YOUR-NETWORKS-REPOSITORY", +# projects = "YOUR-PROJECTS-REPOSITORY", +# } +# +# to prevent saving the `gh_token` in plain text in this file, +# export the GitHub fine grained access token in the command line +# as an environment variable before running terraform. +# Run the following commnad in your shell: +# export TF_VAR_gh_token="YOUR-FINE-GRAINED-ACCESS-TOKEN" + + +/* ---------------------------------------- + Specific to jenkins_bootstrap module + ---------------------------------------- */ +# Un-comment the jenkins_bootstrap module and its outputs if you want to use Jenkins instead of Cloud Build +# jenkins_agent_gce_subnetwork_cidr_range = "172.16.1.0/24" +# +# jenkins_agent_gce_private_ip_address = "172.16.1.6" +# +# jenkins_agent_gce_ssh_pub_key = "ssh-rsa [KEY_VALUE] [USERNAME]" +# +# jenkins_agent_sa_email = "jenkins-agent-gce" # service_account_prefix will be added +# +# jenkins_controller_subnetwork_cidr_range = ["10.1.0.6/32"] +# +# nat_bgp_asn = "64514" +# +# vpn_shared_secret = "shared_secret" +# +# on_prem_vpn_public_ip_address = "" +# +# on_prem_vpn_public_ip_address2 = "" +# +# router_asn = "64515" +# +# bgp_peer_asn = "64513" +# +# tunnel0_bgp_peer_address = "169.254.1.1" +# +# tunnel0_bgp_session_range = "169.254.1.2/30" +# +# tunnel1_bgp_peer_address = "169.254.2.1" +# +# tunnel1_bgp_session_range = "169.254.2.2/30" + +/* ---------------------------------------- + Specific to gitlab_bootstrap + ---------------------------------------- */ +# Un-comment gitlab_bootstrap and its outputs if you want to use GitLab CI/CD instead of Cloud Build +# gl_repos = { +# owner = "YOUR-GITLAB-USER-OR-GROUP", +# bootstrap = "YOUR-BOOTSTRAP-REPOSITORY", +# organization = "YOUR-ORGANIZATION-REPOSITORY", +# environments = "YOUR-ENVIRONMENTS-REPOSITORY", +# networks = "YOUR-NETWORKS-REPOSITORY", +# projects = "YOUR-PROJECTS-REPOSITORY", +# cicd_runner = "YOUR-CICD-RUNNER-REPOSITORY", +# } +# +# to prevent saving the `gitlab_token` in plain text in this file, +# export the GitLab access token in the command line +# as an environment variable before running terraform. +# Run the following commnad in your shell: +# export TF_VAR_gitlab_token="YOUR-ACCESS-TOKEN" + +/* ---------------------------------------- + Specific to tfc_bootstrap + ---------------------------------------- */ +// Un-comment tfc_bootstrap and its outputs if you want to use Terraform Cloud instead of Cloud Build +// Format expected: REPO-OWNER/REPO-NAME +# vcs_repos = { +# owner = "YOUR-VCS-USER-OR-ORGANIZATION", +# bootstrap = "YOUR-BOOTSTRAP-REPOSITORY", +# organization = "YOUR-ORGANIZATION-REPOSITORY", +# environments = "YOUR-ENVIRONMENTS-REPOSITORY", +# networks = "YOUR-NETWORKS-REPOSITORY", +# projects = "YOUR-PROJECTS-REPOSITORY", +# } +# tfc_org_name = "REPLACE_ME" + + +// Set this to true if you want to use Terraform Cloud Agents instead of Terraform Cloud remote runner +// If true, a private Autopilot GKE cluster will be created in your GCP account to be used as Terraform Cloud Agents +// More info about Agents on: https://developer.hashicorp.com/terraform/cloud-docs/agents + +# enable_tfc_cloud_agents = false + +// to prevent saving the `tfc_token` in plain text in this file, +// export the Terraform Cloud token in the command line +// as an environment variable before running terraform. +// Run the following commnad in your shell: +// export TF_VAR_tfc_token="YOUR-TFC-TOKEN" + +// For VCS connection based in OAuth: (GitHub OAuth/GitHub Enterprise/Gitlab.com/GitLab Enterprise or Community Edition) +// to prevent saving the `vcs_oauth_token_id` in plain text in this file, +// export the Terraform Cloud VCS Connection OAuth token ID in the command line +// as an environment variable before running terraform. + +// Note: you should be able to copy `OAuth Token ID` (vcs_oauth_token_id) in TFC console: +// https://app.terraform.io/app/YOUR-TFC-ORGANIZATION/settings/version-control + +// Run the following commnad in your shell: +// export TF_VAR_vcs_oauth_token_id="YOUR-VCS-OAUTH-TOKEN-ID" + +// For GitHub OAuth see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/github +// For GitHub Enterprise see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/github-enterprise +// For GitLab.com see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/gitlab-com +// For GitLab EE/CE see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/gitlab-eece \ No newline at end of file From 62106326ac000730239b5f69bcb8499457a280f1 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 16:17:56 -0300 Subject: [PATCH 039/114] fix README --- 1-org/README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/1-org/README.md b/1-org/README.md index 469aa1d35..7c854ffcd 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -173,7 +173,7 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f if [ ! -z "${ACCESS_CONTEXT_MANAGER_ID}" ]; then sed -i'' -e "s=//create_access_context_manager_access_policy=create_access_context_manager_access_policy=" ./envs/shared/terraform.tfvars; fi ``` -2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: ``` { @@ -200,7 +200,7 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f }, ``` -3. Run `terraform init` in `/envs/shared` to generate the outputs used in other steps. +1. Run `terraform init` in `/envs/shared` to generate the outputs used in other steps. ```bash cd envs/shared @@ -208,14 +208,14 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f cd ../.. ``` -4. Commit changes. +1. Commit changes. ```bash git add . git commit -m 'Initialize org repo' ``` -5. Push your plan branch to trigger a plan for all environments. Because the +1. Push your plan branch to trigger a plan for all environments. Because the _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing your _plan_ branch triggers _terraform plan_ but not _terraform apply_. Review the plan output in your Cloud Build project. @@ -223,7 +223,7 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f git push --set-upstream origin plan ``` -6. Merge changes to the production branch. Because the _production_ branch is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +1. Merge changes to the production branch. Because the _production_ branch is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project. ```bash @@ -231,7 +231,7 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f git push origin production ``` -7. Proceed to the [2-environments](../2-environments/README.md) step. +1. Proceed to the [2-environments](../2-environments/README.md) step. **Troubleshooting:** If you received a `PERMISSION_DENIED` error while running the `gcloud access-context-manager` or the `gcloud scc notifications` commands, you can append the following to run the command as the Terraform service account: @@ -297,7 +297,7 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./envs/shared/terraform.tfvars ``` -2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: ``` { @@ -324,7 +324,7 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu }, ``` -3. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. +1. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) From 8999cd4e9f9f96ced886a107b8990c53a8618ef6 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 16:57:56 -0300 Subject: [PATCH 040/114] fixes 1-0rg --- 1-org/envs/shared/outputs.tf | 5 ----- 1-org/envs/shared/terraform.example.tfvars | 2 +- 1-org/envs/shared/variables.tf | 6 +++--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/1-org/envs/shared/outputs.tf b/1-org/envs/shared/outputs.tf index b1ec93863..51e80fa67 100644 --- a/1-org/envs/shared/outputs.tf +++ b/1-org/envs/shared/outputs.tf @@ -179,11 +179,6 @@ output "access_context_manager_policy_id" { description = "Access Context Manager Policy ID." } -output "build_service_account" { - description = "Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container." - value = google_service_account.cai_monitoring_builder[0].email -} - output "log_export_billing" { description = "The service account that logging uses to write log entries to the destination." value = module.logs_export.log_export_billing diff --git a/1-org/envs/shared/terraform.example.tfvars b/1-org/envs/shared/terraform.example.tfvars index cd15c086c..22356e0af 100644 --- a/1-org/envs/shared/terraform.example.tfvars +++ b/1-org/envs/shared/terraform.example.tfvars @@ -44,4 +44,4 @@ billing_export_dataset_location = "US" //create_unique_tag_key = true -access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID \ No newline at end of file +access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index 486c2966a..c494ef8e0 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -29,7 +29,7 @@ variable "enable_hub_and_spoke" { variable "enable_scc_resources_in_terraform" { description = "Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context." type = bool - default = true + default = false } variable "enable_kms_key_usage_tracking" { @@ -173,12 +173,12 @@ variable "essential_contacts_language" { } variable "remote_state_bucket" { - description = "Backend bucket to load Terraform Remote State Data from previous steps.." + description = "Backend bucket to load Terraform Remote State Data from previous steps." type = string } variable "essential_contacts_domains_to_allow" { - description = ".The list of domains that email addresses added to Essential Contacts can have." + description = "The list of domains that email addresses added to Essential Contacts can have." type = list(string) } From e6980a084842fed50e773aa5743eaf09307ff64e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 17:01:01 -0300 Subject: [PATCH 041/114] fix hub and spoke network README --- 3-networks-hub-and-spoke/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/3-networks-hub-and-spoke/README.md b/3-networks-hub-and-spoke/README.md index 6df4cd70a..a4af0f68a 100644 --- a/3-networks-hub-and-spoke/README.md +++ b/3-networks-hub-and-spoke/README.md @@ -193,16 +193,16 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` -2. Commit changes +1. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -3. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -4. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -5. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +1. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +1. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +1. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -212,26 +212,26 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -6. Run `init` and `plan` and review output for environment shared. +1. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -7. Run `validate` and check for violations. +1. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -8. Run `apply` shared. +1. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -9. Push your plan branch to trigger a plan for all environments. Because the +1. Push your plan branch to trigger a plan for all environments. Because the _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch)), pushing your _plan_ branch triggers _terraform plan_ but not _terraform apply_. Review the plan output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID @@ -239,7 +239,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push --set-upstream origin plan ``` -10. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +1. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -247,7 +247,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin production ``` -11. After production has been applied, apply development. +1. After production has been applied, apply development. 1. Merge changes to development. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID @@ -256,8 +256,8 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin development ``` -2. After development has been applied, apply nonproduction. -3. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +1. After development has been applied, apply nonproduction. +1. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -265,13 +265,13 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin nonproduction ``` -4. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +1. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -5. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. +1. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. ### Deploying with Jenkins From 0053fda860b9413cc0917c988a14ca67ec6464b2 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 17:04:10 -0300 Subject: [PATCH 042/114] rm duplicate --- 3-networks-hub-and-spoke/modules/base_env/main.tf | 1 - 1 file changed, 1 deletion(-) diff --git a/3-networks-hub-and-spoke/modules/base_env/main.tf b/3-networks-hub-and-spoke/modules/base_env/main.tf index 523b30304..618944c11 100644 --- a/3-networks-hub-and-spoke/modules/base_env/main.tf +++ b/3-networks-hub-and-spoke/modules/base_env/main.tf @@ -92,6 +92,5 @@ module "shared_vpc" { ] secondary_ranges = { "sb-${var.environment_code}-svpc-${var.default_region1}" = var.subnet_secondary_ranges[var.default_region1] - "sb-${var.environment_code}-svpc-${var.default_region1}" = var.subnet_secondary_ranges[var.default_region1] } } From 358b1442e05354c9c61b9af2e0890afcdae19913 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 17:05:45 -0300 Subject: [PATCH 043/114] fix README --- 3-networks-svpc/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/3-networks-svpc/README.md b/3-networks-svpc/README.md index e89b51c75..52ddcd8b3 100644 --- a/3-networks-svpc/README.md +++ b/3-networks-svpc/README.md @@ -189,16 +189,16 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` -2. Commit changes +1. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -3. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -4. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -5. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +1. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +1. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +1. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -208,46 +208,46 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -6. Run `init` and `plan` and review output for environment shared. +1. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -7. Run `validate` and check for violations. +1. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -8. Run `apply` shared. +1. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -9. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. +1. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. ```bash git checkout -b production ``` -10. Run `init` and `plan` and review output for environment production. +1. Run `init` and `plan` and review output for environment production. ```bash ./tf-wrapper.sh init production ./tf-wrapper.sh plan production ``` -11. Run `apply` production. +1. Run `apply` production. ```bash ./tf-wrapper.sh apply production ``` - 1. Push your production branch since development and nonproduction depends it. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), - pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID +1. Push your production branch since development and nonproduction depends it. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID *Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. From 66b6bc2cce7780f15080067181dfd3e17d6d81dd Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 17:06:47 -0300 Subject: [PATCH 044/114] fix 4-projects README --- 4-projects/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/4-projects/README.md b/4-projects/README.md index e2f8e7b32..1c111b048 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -220,14 +220,14 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' git push origin nonproduction ``` -2. Use `terraform output` to get the APP Infra Pipeline Terraform service account. +1. Use `terraform output` to get the APP Infra Pipeline Terraform service account. ```bash export terraform_service_accounts=$(terraform -chdir="business_unit_1/shared/" output -json terraform_service_accounts | jq -r 'to_entries[0].value') echo $terraform_service_accounts ``` -3. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: ``` { @@ -282,13 +282,13 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' }, ``` -4. Before executing the next step, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +1. Before executing the next step, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -5. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. +1. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. ### Deploying with Jenkins @@ -471,7 +471,7 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' echo $terraform_service_accounts ``` -3. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: ``` { From df5208f61e82cd3405707f551e407d58e1388727 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 7 Aug 2025 17:11:04 -0300 Subject: [PATCH 045/114] add outputs descriptions and fix READMES --- 1-org/envs/shared/README.md | 6 +++--- 4-projects/business_unit_1/shared/README.md | 4 ++-- 4-projects/business_unit_1/shared/outputs.tf | 6 ++++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index e2db0573e..ca460c78b 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -14,9 +14,9 @@ | egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |

list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
external_resources = optional(list(string), [])
})
}))
| `[]` | no | | enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_kms\_key\_usage\_tracking | Enable KMS centralized key usage tracking system. | `bool` | `true` | no | -| enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context. | `bool` | `true` | no | +| enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context. | `bool` | `false` | no | | enforce\_allowed\_worker\_pools | Whether to enforce the organization policy restriction on allowed worker pools for Cloud Build. | `bool` | `false` | no | -| essential\_contacts\_domains\_to\_allow | .The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes | +| essential\_contacts\_domains\_to\_allow | The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes | | essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no | | folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | no | | gcp\_groups | Groups to grant specific roles in the Organization.
platform\_viewer: Google Workspace or Cloud Identity group that have the ability to view resource information across the Google Cloud organization.
security\_reviewer: Google Workspace or Cloud Identity group that members are part of the security team responsible for reviewing cloud security
network\_viewer: Google Workspace or Cloud Identity group that members are part of the networking team and review network configurations.
scc\_admin: Google Workspace or Cloud Identity group that can administer Security Command Center.
audit\_viewer: Google Workspace or Cloud Identity group that members are part of an audit team and view audit logs in the logging project.
global\_secrets\_admin: Google Workspace or Cloud Identity group that members are responsible for putting secrets into Secrets Management. |
object({
audit_viewer = optional(string, null)
security_reviewer = optional(string, null)
network_viewer = optional(string, null)
scc_admin = optional(string, null)
global_secrets_admin = optional(string, null)
kms_admin = optional(string, null)
})
| `{}` | no | @@ -30,7 +30,7 @@ | perimeter\_additional\_members\_dry\_run | The list of additional members to be added to the dry-run perimeter access level members list. To be able to see the resources protected by the VPC Service Controls in the perimeter, add your user in this list. Entries must be in the standard GCP form: `user:email@example.com` or `serviceAccount:my-service-account@example.com`. | `list(string)` | `[]` | no | | project\_budget | Budget configuration for projects.
budget\_amount: The amount to use as the budget.
alert\_spent\_percents: A list of percentages of the budget to alert on when threshold is exceeded.
alert\_pubsub\_topic: The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`.
alert\_spend\_basis: The type of basis used to determine if spend has passed the threshold. Possible choices are `CURRENT_SPEND` or `FORECASTED_SPEND` (default). |
object({
net_hub_budget_amount = optional(number, 1000)
net_hub_alert_spent_percents = optional(list(number), [1.2])
net_hub_alert_pubsub_topic = optional(string, null)
net_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
shared_network_budget_amount = optional(number, 1000)
shared_network_alert_spent_percents = optional(list(number), [1.2])
shared_network_alert_pubsub_topic = optional(string, null)
shared_network_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
interconnect_budget_amount = optional(number, 1000)
interconnect_alert_spent_percents = optional(list(number), [1.2])
interconnect_alert_pubsub_topic = optional(string, null)
interconnect_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_secrets_budget_amount = optional(number, 1000)
org_secrets_alert_spent_percents = optional(list(number), [1.2])
org_secrets_alert_pubsub_topic = optional(string, null)
org_secrets_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_billing_export_budget_amount = optional(number, 1000)
org_billing_export_alert_spent_percents = optional(list(number), [1.2])
org_billing_export_alert_pubsub_topic = optional(string, null)
org_billing_export_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_audit_logs_budget_amount = optional(number, 1000)
org_audit_logs_alert_spent_percents = optional(list(number), [1.2])
org_audit_logs_alert_pubsub_topic = optional(string, null)
org_audit_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
common_kms_budget_amount = optional(number, 1000)
common_kms_alert_spent_percents = optional(list(number), [1.2])
common_kms_alert_pubsub_topic = optional(string, null)
common_kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
scc_notifications_budget_amount = optional(number, 1000)
scc_notifications_alert_spent_percents = optional(list(number), [1.2])
scc_notifications_alert_pubsub_topic = optional(string, null)
scc_notifications_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
})
| `{}` | no | | project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no | -| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps.. | `string` | n/a | yes | +| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | resources | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. | `list(string)` | `[]` | no | | resources\_dry\_run | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set. | `list(string)` | `[]` | no | | scc\_notification\_filter | Filter used to create the Security Command Center Notification, you can see more details on how to create filters in https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications#create-filter | `string` | `"state = \"ACTIVE\""` | no | diff --git a/4-projects/business_unit_1/shared/README.md b/4-projects/business_unit_1/shared/README.md index 00dd83ea7..f2c824ef0 100644 --- a/4-projects/business_unit_1/shared/README.md +++ b/4-projects/business_unit_1/shared/README.md @@ -15,8 +15,8 @@ |------|-------------| | apply\_triggers\_id | CB apply triggers | | artifact\_buckets | GCS Buckets to store Cloud Build Artifacts | -| cloudbuild\_project\_id | n/a | -| cloudbuild\_project\_number | n/a | +| cloudbuild\_project\_id | APP Infra cloudbuild project id. | +| cloudbuild\_project\_number | APP Infra cloudbuild project number. | | default\_region | Default region to create resources where applicable. | | enable\_cloudbuild\_deploy | Enable infra deployment using Cloud Build. | | log\_buckets | GCS Buckets to store Cloud Build logs | diff --git a/4-projects/business_unit_1/shared/outputs.tf b/4-projects/business_unit_1/shared/outputs.tf index c3abff1a7..6964c3420 100644 --- a/4-projects/business_unit_1/shared/outputs.tf +++ b/4-projects/business_unit_1/shared/outputs.tf @@ -20,11 +20,13 @@ output "default_region" { } output "cloudbuild_project_id" { - value = try(module.app_infra_cloudbuild_project[0].project_id, "") + description = "APP Infra cloudbuild project id." + value = try(module.app_infra_cloudbuild_project[0].project_id, "") } output "cloudbuild_project_number" { - value = module.app_infra_cloudbuild_project[0].project_number + description = "APP Infra cloudbuild project number." + value = module.app_infra_cloudbuild_project[0].project_number } output "terraform_service_accounts" { From a68fe3bc9e0df9355abf3b2edc2b45db1d057616 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 8 Aug 2025 16:48:04 -0300 Subject: [PATCH 046/114] add comment in cloud function module --- 1-org/modules/cai-monitoring/main.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/1-org/modules/cai-monitoring/main.tf b/1-org/modules/cai-monitoring/main.tf index 77d391902..8c927aba4 100644 --- a/1-org/modules/cai-monitoring/main.tf +++ b/1-org/modules/cai-monitoring/main.tf @@ -140,6 +140,8 @@ resource "google_scc_source" "cai_monitoring" { } // Cloud Function +//Using branch 'release-please--branches--main' due to Registry v0.6 incompability with Google Provider. +//TODO: update to the latest Registry version when released. module "cloud_function" { source = "git::https://github.com/GoogleCloudPlatform/terraform-google-cloud-functions.git?ref=release-please--branches--main" # source = "GoogleCloudPlatform/cloud-functions/google" From a5e34495aabd2425100e9f2c3f036cd6b50da889 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 8 Aug 2025 17:15:12 -0300 Subject: [PATCH 047/114] add subnet_region variable --- 0-bootstrap/modules/cb-private-pool/README.md | 1 + 0-bootstrap/modules/cb-private-pool/network.tf | 2 +- 0-bootstrap/modules/cb-private-pool/variables.tf | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/0-bootstrap/modules/cb-private-pool/README.md b/0-bootstrap/modules/cb-private-pool/README.md index 9411e7db5..cac726f5c 100644 --- a/0-bootstrap/modules/cb-private-pool/README.md +++ b/0-bootstrap/modules/cb-private-pool/README.md @@ -5,6 +5,7 @@ |------|-------------|------|---------|:--------:| | private\_worker\_pool | name: Name of the worker pool. A name with a random suffix is generated if not set.
region: The private worker pool region. See https://cloud.google.com/build/docs/locations for available locations.
disk\_size\_gb: Size of the disk attached to the worker, in GB.
machine\_type: Machine type of a worker.
no\_external\_ip: If true, workers are created without any public address, which prevents network egress to public IPs.
enable\_network\_peering: Set to true to enable configuration of networking peering for the private worker pool.
create\_peered\_network: If true a network will be created to stablish the network peering.
peered\_network\_id: The ID of the existing network to configure peering for the private worker pool if create\_peered\_network false. The project containing the network must have Service Networking API (`servicenetworking.googleapis.com`) enabled.
peered\_network\_subnet\_ip: The IP range to be used for the subnet that a will created in the peered network if create\_peered\_network true.
peering\_address: The IP address or beginning of the peering address range. This can be supplied as an input to reserve a specific address or omitted to allow GCP to choose a valid one.
peering\_prefix\_length: The prefix length of the IP peering range. If not present, it means the address field is a single IP address. |
object({
name = optional(string, "")
region = optional(string, "us-central1")
disk_size_gb = optional(number, 100)
machine_type = optional(string, "e2-medium")
no_external_ip = optional(bool, true)
enable_network_peering = optional(bool, true)
create_peered_network = optional(bool, true)
peered_network_id = optional(string, "")
peered_network_subnet_ip = optional(string, "")
peering_address = optional(string, null)
peering_prefix_length = optional(number, 24)
})
| `{}` | no | | project\_id | ID of the project where the private pool will be created | `string` | n/a | yes | +| subnet\_region | Region where a subnet will be created in the sigle project network. | `string` | `"us-central1"` | no | | vpc\_flow\_logs | aggregation\_interval: Toggles the aggregation interval for collecting flow logs. Increasing the interval time will reduce the amount of generated flow logs for long lasting connections. Possible values are: INTERVAL\_5\_SEC, INTERVAL\_30\_SEC, INTERVAL\_1\_MIN, INTERVAL\_5\_MIN, INTERVAL\_10\_MIN, INTERVAL\_15\_MIN.
flow\_sampling: Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported. The value of the field must be in [0, 1].
metadata: Configures whether metadata fields should be added to the reported VPC flow logs. Possible values are: EXCLUDE\_ALL\_METADATA, INCLUDE\_ALL\_METADATA, CUSTOM\_METADATA.
metadata\_fields: ist of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and "metadata" is set to CUSTOM\_METADATA.
filter\_expr: Export filter used to define which VPC flow logs should be logged, as as CEL expression. See https://cloud.google.com/vpc/docs/flow-logs#filtering for details on how to format this field. |
object({
aggregation_interval = optional(string, "INTERVAL_5_SEC")
flow_sampling = optional(string, "0.5")
metadata = optional(string, "INCLUDE_ALL_METADATA")
metadata_fields = optional(list(string), [])
filter_expr = optional(string, "true")
})
| `{}` | no | | vpn\_configuration | enable\_vpn: set to true to create VPN connection to on prem. If true, the following values must be valid.
on\_prem\_public\_ip\_address0: The first public IP address for on prem VPN connection.
on\_prem\_public\_ip\_address1: The second public IP address for on prem VPN connection.
router\_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for cloud routes.
bgp\_peer\_asn: Border Gateway Protocol (BGP) Autonomous System Number (ASN) for peer cloud routes.
shared\_secret: The shared secret used in the VPN.
psk\_secret\_project\_id: The ID of the project that contains the secret from secret manager that holds the VPN pre-shared key.
psk\_secret\_name: The name of the secret to retrieve from secret manager that holds the VPN pre-shared key.
tunnel0\_bgp\_peer\_address: BGP peer address for tunnel 0.
tunnel0\_bgp\_session\_range: BGP session range for tunnel 0.
tunnel1\_bgp\_peer\_address: BGP peer address for tunnel 1.
tunnel1\_bgp\_session\_range: BGP session range for tunnel 1. |
object({
enable_vpn = optional(bool, false)
on_prem_public_ip_address0 = optional(string, "")
on_prem_public_ip_address1 = optional(string, "")
router_asn = optional(number, 64515)
bgp_peer_asn = optional(number, 64513)
psk_secret_project_id = optional(string, "")
psk_secret_name = optional(string, "")
tunnel0_bgp_peer_address = optional(string, "")
tunnel0_bgp_session_range = optional(string, "")
tunnel1_bgp_peer_address = optional(string, "")
tunnel1_bgp_session_range = optional(string, "")
})
| `{}` | no | diff --git a/0-bootstrap/modules/cb-private-pool/network.tf b/0-bootstrap/modules/cb-private-pool/network.tf index fa014f932..92f615d77 100644 --- a/0-bootstrap/modules/cb-private-pool/network.tf +++ b/0-bootstrap/modules/cb-private-pool/network.tf @@ -22,7 +22,7 @@ locals { single_project_network = { subnet_name = "eab-develop-us-central1" subnet_ip = "10.1.20.0/24" - subnet_region = "us-central1" + subnet_region = var.subnet_region subnet_private_access = true } single_project_secondary = { diff --git a/0-bootstrap/modules/cb-private-pool/variables.tf b/0-bootstrap/modules/cb-private-pool/variables.tf index 1639223ce..38ec91c41 100644 --- a/0-bootstrap/modules/cb-private-pool/variables.tf +++ b/0-bootstrap/modules/cb-private-pool/variables.tf @@ -124,3 +124,9 @@ EOT }) default = {} } + +variable "subnet_region" { + description = "Region where a subnet will be created in the sigle project network." + type = string + default = "us-central1" +} From ed7a0228252acdcd0a10fb64904a886ba792f07c Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 8 Aug 2025 17:15:40 -0300 Subject: [PATCH 048/114] rm access context manager policy id in network steps --- 3-networks-hub-and-spoke/README.md | 55 ++++++------------- .../access_context.auto.example.tfvars | 17 ------ .../envs/development/README.md | 2 - .../envs/development/main.tf | 1 - .../envs/development/outputs.tf | 5 -- .../envs/development/variables.tf | 5 -- .../envs/nonproduction/README.md | 2 - .../envs/nonproduction/main.tf | 1 - .../envs/nonproduction/outputs.tf | 5 -- .../envs/nonproduction/variables.tf | 5 -- .../envs/production/README.md | 2 - .../envs/production/main.tf | 1 - .../envs/production/outputs.tf | 5 -- .../envs/production/variables.tf | 5 -- .../envs/shared/README.md | 1 - .../envs/shared/net-hubs.tf | 37 ++++++------- .../envs/shared/variables.tf | 5 -- .../modules/base_env/README.md | 1 - .../modules/base_env/main.tf | 27 +++++---- .../modules/base_env/variables.tf | 5 -- .../modules/shared_vpc/README.md | 1 - .../modules/shared_vpc/variables.tf | 5 -- 3-networks-svpc/README.md | 54 +++++------------- .../access_context.auto.example.tfvars | 17 ------ 3-networks-svpc/envs/development/README.md | 2 - 3-networks-svpc/envs/development/main.tf | 1 - 3-networks-svpc/envs/development/outputs.tf | 5 -- 3-networks-svpc/envs/development/variables.tf | 5 -- 3-networks-svpc/envs/nonproduction/README.md | 2 - 3-networks-svpc/envs/nonproduction/main.tf | 1 - 3-networks-svpc/envs/nonproduction/outputs.tf | 5 -- .../envs/nonproduction/variables.tf | 5 -- 3-networks-svpc/envs/production/README.md | 2 - 3-networks-svpc/envs/production/main.tf | 1 - 3-networks-svpc/envs/production/outputs.tf | 5 -- 3-networks-svpc/envs/production/variables.tf | 5 -- 3-networks-svpc/modules/base_env/README.md | 1 - 3-networks-svpc/modules/base_env/main.tf | 23 ++++---- 3-networks-svpc/modules/base_env/variables.tf | 5 -- 3-networks-svpc/modules/shared_vpc/README.md | 1 - .../modules/shared_vpc/variables.tf | 5 -- 41 files changed, 73 insertions(+), 265 deletions(-) delete mode 100644 3-networks-hub-and-spoke/access_context.auto.example.tfvars delete mode 100644 3-networks-svpc/access_context.auto.example.tfvars diff --git a/3-networks-hub-and-spoke/README.md b/3-networks-hub-and-spoke/README.md index a4af0f68a..71aeda615 100644 --- a/3-networks-hub-and-spoke/README.md +++ b/3-networks-hub-and-spoke/README.md @@ -65,14 +65,6 @@ The purpose of this step is to: 1. 0-bootstrap executed successfully. 1. 1-org executed successfully. 1. 2-environments executed successfully. -1. Obtain the value for the access_context_manager_policy_id variable. It can be obtained by running the following commands. We assume you are at the same level as directory `terraform-example-foundation`, If you run them from another directory, adjust your paths accordingly. - - ```bash - export ORGANIZATION_ID=$(terraform -chdir="terraform-example-foundation/0-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - ``` - 1. For the manual step described in this document, you need to use the same [Terraform](https://www.terraform.io/downloads.html) version used on the build pipeline. Otherwise, you might experience Terraform state snapshot lock errors. @@ -177,32 +169,25 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get 1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. Update `shared.auto.tfvars` file with the `target_name_server_addresses`. - Update `access_context.auto.tfvars` file with the `access_context_manager_policy_id`. Use `terraform output` to get the backend bucket value from 0-bootstrap output. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - - sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./access_context.auto.tfvars - export backend_bucket=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` -1. Commit changes +2. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -1. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -1. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -1. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +3. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +4. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +5. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -212,26 +197,26 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -1. Run `init` and `plan` and review output for environment shared. +6. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -1. Run `validate` and check for violations. +7. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -1. Run `apply` shared. +8. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -1. Push your plan branch to trigger a plan for all environments. Because the +9. Push your plan branch to trigger a plan for all environments. Because the _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch)), pushing your _plan_ branch triggers _terraform plan_ but not _terraform apply_. Review the plan output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID @@ -239,7 +224,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push --set-upstream origin plan ``` -1. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +10. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -247,8 +232,8 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin production ``` -1. After production has been applied, apply development. -1. Merge changes to development. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +11. After production has been applied, apply development. +12. Merge changes to development. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -256,8 +241,8 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin development ``` -1. After development has been applied, apply nonproduction. -1. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +13. After development has been applied, apply nonproduction. +14. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -265,13 +250,13 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin nonproduction ``` -1. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +15. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -1. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. +16. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. ### Deploying with Jenkins @@ -309,21 +294,13 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s ```bash mv common.auto.example.tfvars common.auto.tfvars mv shared.auto.example.tfvars shared.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. 1. Update `shared.auto.tfvars` file with the `target_name_server_addresses`. -1. Update `access_context.auto.tfvars` file with the `access_context_manager_policy_id`. -1. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. +2. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../gcp-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - - sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./access_context.auto.tfvars - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" diff --git a/3-networks-hub-and-spoke/access_context.auto.example.tfvars b/3-networks-hub-and-spoke/access_context.auto.example.tfvars deleted file mode 100644 index 346e3f720..000000000 --- a/3-networks-hub-and-spoke/access_context.auto.example.tfvars +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2022 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID diff --git a/3-networks-hub-and-spoke/envs/development/README.md b/3-networks-hub-and-spoke/envs/development/README.md index 6039fc7f8..f1253478b 100644 --- a/3-networks-hub-and-spoke/envs/development/README.md +++ b/3-networks-hub-and-spoke/envs/development/README.md @@ -15,7 +15,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | @@ -25,7 +24,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | shared\_vpc\_host\_project\_id | The host project ID | diff --git a/3-networks-hub-and-spoke/envs/development/main.tf b/3-networks-hub-and-spoke/envs/development/main.tf index e18b8187a..081b76d86 100644 --- a/3-networks-hub-and-spoke/envs/development/main.tf +++ b/3-networks-hub-and-spoke/envs/development/main.tf @@ -46,7 +46,6 @@ module "base_env" { env = local.env environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain diff --git a/3-networks-hub-and-spoke/envs/development/outputs.tf b/3-networks-hub-and-spoke/envs/development/outputs.tf index 6e6c5b4eb..adc89e11e 100644 --- a/3-networks-hub-and-spoke/envs/development/outputs.tf +++ b/3-networks-hub-and-spoke/envs/development/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The host project ID" diff --git a/3-networks-hub-and-spoke/envs/development/variables.tf b/3-networks-hub-and-spoke/envs/development/variables.tf index 614135775..c86550386 100644 --- a/3-networks-hub-and-spoke/envs/development/variables.tf +++ b/3-networks-hub-and-spoke/envs/development/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." diff --git a/3-networks-hub-and-spoke/envs/nonproduction/README.md b/3-networks-hub-and-spoke/envs/nonproduction/README.md index a01f37ef8..f14b1c741 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/README.md +++ b/3-networks-hub-and-spoke/envs/nonproduction/README.md @@ -15,7 +15,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | @@ -25,7 +24,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | diff --git a/3-networks-hub-and-spoke/envs/nonproduction/main.tf b/3-networks-hub-and-spoke/envs/nonproduction/main.tf index bb6ebde05..2a7287538 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/main.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/main.tf @@ -46,7 +46,6 @@ module "base_env" { env = local.env environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain diff --git a/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf b/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf index 0ec049063..0a8733624 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" diff --git a/3-networks-hub-and-spoke/envs/nonproduction/variables.tf b/3-networks-hub-and-spoke/envs/nonproduction/variables.tf index 614135775..c86550386 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/variables.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." diff --git a/3-networks-hub-and-spoke/envs/production/README.md b/3-networks-hub-and-spoke/envs/production/README.md index 480f30e16..4652741e7 100644 --- a/3-networks-hub-and-spoke/envs/production/README.md +++ b/3-networks-hub-and-spoke/envs/production/README.md @@ -15,7 +15,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | @@ -25,7 +24,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | diff --git a/3-networks-hub-and-spoke/envs/production/main.tf b/3-networks-hub-and-spoke/envs/production/main.tf index f4f56e560..bfbbf627f 100644 --- a/3-networks-hub-and-spoke/envs/production/main.tf +++ b/3-networks-hub-and-spoke/envs/production/main.tf @@ -46,7 +46,6 @@ module "base_env" { env = local.env environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain diff --git a/3-networks-hub-and-spoke/envs/production/outputs.tf b/3-networks-hub-and-spoke/envs/production/outputs.tf index 0ec049063..0a8733624 100644 --- a/3-networks-hub-and-spoke/envs/production/outputs.tf +++ b/3-networks-hub-and-spoke/envs/production/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" diff --git a/3-networks-hub-and-spoke/envs/production/variables.tf b/3-networks-hub-and-spoke/envs/production/variables.tf index 614135775..c86550386 100644 --- a/3-networks-hub-and-spoke/envs/production/variables.tf +++ b/3-networks-hub-and-spoke/envs/production/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." diff --git a/3-networks-hub-and-spoke/envs/shared/README.md b/3-networks-hub-and-spoke/envs/shared/README.md index cd823fd06..0c47a3896 100644 --- a/3-networks-hub-and-spoke/envs/shared/README.md +++ b/3-networks-hub-and-spoke/envs/shared/README.md @@ -12,7 +12,6 @@ The purpose of this step is to set up the global [DNS Hub](https://cloud.google. | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | bgp\_asn\_dns | BGP Autonomous System Number (ASN). | `number` | `64667` | no | | dns\_enable\_logging | Toggle DNS logging for VPC DNS. | `bool` | `true` | no | | dns\_vpc\_flow\_logs | enable\_logging: set to true to enable VPC flow logging for the subnetworks.
aggregation\_interval: Toggles the aggregation interval for collecting flow logs. Increasing the interval time will reduce the amount of generated flow logs for long lasting connections. Possible values are: INTERVAL\_5\_SEC, INTERVAL\_30\_SEC, INTERVAL\_1\_MIN, INTERVAL\_5\_MIN, INTERVAL\_10\_MIN, INTERVAL\_15\_MIN.
flow\_sampling: Set the sampling rate of VPC flow logs within the subnetwork where 1.0 means all collected logs are reported and 0.0 means no logs are reported. The value of the field must be in [0, 1].
metadata: Configures whether metadata fields should be added to the reported VPC flow logs. Possible values are: EXCLUDE\_ALL\_METADATA, INCLUDE\_ALL\_METADATA, CUSTOM\_METADATA.
metadata\_fields: ist of metadata fields that should be added to reported logs. Can only be specified if VPC flow logs for this subnetwork is enabled and "metadata" is set to CUSTOM\_METADATA.
filter\_expr: Export filter used to define which VPC flow logs should be logged, as as CEL expression. See https://cloud.google.com/vpc/docs/flow-logs#filtering for details on how to format this field. |
object({
enable_logging = optional(string, "true")
aggregation_interval = optional(string, "INTERVAL_5_SEC")
flow_sampling = optional(string, "0.5")
metadata = optional(string, "INCLUDE_ALL_METADATA")
metadata_fields = optional(list(string), [])
filter_expr = optional(string, "true")
})
| `{}` | no | diff --git a/3-networks-hub-and-spoke/envs/shared/net-hubs.tf b/3-networks-hub-and-spoke/envs/shared/net-hubs.tf index e887a39d2..f906aa75b 100644 --- a/3-networks-hub-and-spoke/envs/shared/net-hubs.tf +++ b/3-networks-hub-and-spoke/envs/shared/net-hubs.tf @@ -34,25 +34,24 @@ locals { module "shared_vpc" { source = "../../modules/shared_vpc" - project_id = local.net_hub_project_id - project_number = local.net_hub_project_number - environment_code = local.environment_code - private_service_connect_ip = "10.17.0.5" - access_context_manager_policy_id = var.access_context_manager_policy_id - bgp_asn_subnet = local.bgp_asn_number - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - dns_enable_inbound_forwarding = var.hub_dns_enable_inbound_forwarding - dns_enable_logging = var.hub_dns_enable_logging - firewall_enable_logging = var.hub_firewall_enable_logging - nat_enabled = var.hub_nat_enabled - nat_bgp_asn = var.hub_nat_bgp_asn - nat_num_addresses_region1 = var.hub_nat_num_addresses_region1 - nat_num_addresses_region2 = var.hub_nat_num_addresses_region2 - windows_activation_enabled = var.hub_windows_activation_enabled - target_name_server_addresses = var.target_name_server_addresses - mode = "hub" + project_id = local.net_hub_project_id + project_number = local.net_hub_project_number + environment_code = local.environment_code + private_service_connect_ip = "10.17.0.5" + bgp_asn_subnet = local.bgp_asn_number + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + dns_enable_inbound_forwarding = var.hub_dns_enable_inbound_forwarding + dns_enable_logging = var.hub_dns_enable_logging + firewall_enable_logging = var.hub_firewall_enable_logging + nat_enabled = var.hub_nat_enabled + nat_bgp_asn = var.hub_nat_bgp_asn + nat_num_addresses_region1 = var.hub_nat_num_addresses_region1 + nat_num_addresses_region2 = var.hub_nat_num_addresses_region2 + windows_activation_enabled = var.hub_windows_activation_enabled + target_name_server_addresses = var.target_name_server_addresses + mode = "hub" subnets = [ { diff --git a/3-networks-hub-and-spoke/envs/shared/variables.tf b/3-networks-hub-and-spoke/envs/shared/variables.tf index 8bad48e2a..8ce694951 100644 --- a/3-networks-hub-and-spoke/envs/shared/variables.tf +++ b/3-networks-hub-and-spoke/envs/shared/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "dns_enable_logging" { type = bool description = "Toggle DNS logging for VPC DNS." diff --git a/3-networks-hub-and-spoke/modules/base_env/README.md b/3-networks-hub-and-spoke/modules/base_env/README.md index bca9b7489..d72e7f773 100644 --- a/3-networks-hub-and-spoke/modules/base_env/README.md +++ b/3-networks-hub-and-spoke/modules/base_env/README.md @@ -3,7 +3,6 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | diff --git a/3-networks-hub-and-spoke/modules/base_env/main.tf b/3-networks-hub-and-spoke/modules/base_env/main.tf index 618944c11..67ed708db 100644 --- a/3-networks-hub-and-spoke/modules/base_env/main.tf +++ b/3-networks-hub-and-spoke/modules/base_env/main.tf @@ -29,20 +29,19 @@ locals { module "shared_vpc" { source = "../shared_vpc" - project_id = local.shared_vpc_project_id - project_number = local.shared_vpc_project_number - net_hub_project_id = local.net_hub_project_id - net_hub_project_number = local.net_hub_project_number - environment_code = var.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - private_service_cidr = var.private_service_cidr - private_service_connect_ip = var.private_service_connect_ip - bgp_asn_subnet = local.bgp_asn_number - default_region1 = var.default_region1 - default_region2 = var.default_region2 - domain = var.domain - mode = "spoke" - target_name_server_addresses = var.target_name_server_addresses + project_id = local.shared_vpc_project_id + project_number = local.shared_vpc_project_number + net_hub_project_id = local.net_hub_project_id + net_hub_project_number = local.net_hub_project_number + environment_code = var.environment_code + private_service_cidr = var.private_service_cidr + private_service_connect_ip = var.private_service_connect_ip + bgp_asn_subnet = local.bgp_asn_number + default_region1 = var.default_region1 + default_region2 = var.default_region2 + domain = var.domain + mode = "spoke" + target_name_server_addresses = var.target_name_server_addresses subnets = [ { diff --git a/3-networks-hub-and-spoke/modules/base_env/variables.tf b/3-networks-hub-and-spoke/modules/base_env/variables.tf index 9913080c8..cb2d319b9 100644 --- a/3-networks-hub-and-spoke/modules/base_env/variables.tf +++ b/3-networks-hub-and-spoke/modules/base_env/variables.tf @@ -35,11 +35,6 @@ variable "environment_code" { description = "A short form of the folder level resources (environment) within the Google Cloud organization (ex. d)." } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "default_region1" { type = string description = "First subnet region. The shared vpc modules only configures two regions." diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/README.md b/3-networks-hub-and-spoke/modules/shared_vpc/README.md index 3334081ea..43979002e 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/README.md +++ b/3-networks-hub-and-spoke/modules/shared_vpc/README.md @@ -3,7 +3,6 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | bgp\_asn\_subnet | BGP ASN for Subnets cloud routers. | `number` | n/a | yes | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | diff --git a/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf b/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf index cd4fa3a2d..9cfc19e96 100644 --- a/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf +++ b/3-networks-hub-and-spoke/modules/shared_vpc/variables.tf @@ -19,11 +19,6 @@ variable "target_name_server_addresses" { type = list(map(any)) } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "project_id" { type = string description = "Project ID for Shared VPC." diff --git a/3-networks-svpc/README.md b/3-networks-svpc/README.md index 52ddcd8b3..9ff610628 100644 --- a/3-networks-svpc/README.md +++ b/3-networks-svpc/README.md @@ -65,14 +65,6 @@ The purpose of this step is to: 1. 0-bootstrap executed successfully. 1. 1-org executed successfully. 1. 2-environments executed successfully. -1. Obtain the value for the access_context_manager_policy_id variable. It can be obtained by running the following commands. We assume you are at the same level as directory `terraform-example-foundation`, If you run them from another directory, adjust your paths accordingly. - - ```bash - export ORGANIZATION_ID=$(terraform -chdir="terraform-example-foundation/0-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - ``` - 1. For the manual step described in this document, you need to use the same [Terraform](https://www.terraform.io/downloads.html) version used on the build pipeline. Otherwise, you might experience Terraform state snapshot lock errors. @@ -163,42 +155,34 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +2. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` -1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. +3. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. Update `production.auto.tfvars` file with the `target_name_server_addresses`. - Update `access_context.auto.tfvars` file with the `access_context_manager_policy_id`. Use `terraform output` to get the backend bucket value from 0-bootstrap output. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - - sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./access_context.auto.tfvars - export backend_bucket=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` -1. Commit changes +4. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -1. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -1. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -1. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +5. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +6. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +7. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -208,45 +192,45 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -1. Run `init` and `plan` and review output for environment shared. +8. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -1. Run `validate` and check for violations. +9. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -1. Run `apply` shared. +10. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -1. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. +11. You must manually plan and apply the `production` environment since the `development`, `nonproduction` and `plan` environments depend on it. ```bash git checkout -b production ``` -1. Run `init` and `plan` and review output for environment production. +12. Run `init` and `plan` and review output for environment production. ```bash ./tf-wrapper.sh init production ./tf-wrapper.sh plan production ``` -1. Run `apply` production. +13. Run `apply` production. ```bash ./tf-wrapper.sh apply production ``` -1. Push your production branch since development and nonproduction depends it. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +14. Push your production branch since development and nonproduction depends it. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID *Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. @@ -330,26 +314,18 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. 1. Update `production.auto.tfvars` file with the `target_name_server_addresses`. -1. Update `access_context.auto.tfvars` file with the `access_context_manager_policy_id`. -1. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. +2. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../gcp-bootstrap/" output -json common_config | jq '.org_id' --raw-output) - export ACCESS_CONTEXT_MANAGER_ID=$(gcloud access-context-manager policies list --organization ${ORGANIZATION_ID} --format="value(name)") - echo "access_context_manager_policy_id = ${ACCESS_CONTEXT_MANAGER_ID}" - - sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./access_context.auto.tfvars - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" diff --git a/3-networks-svpc/access_context.auto.example.tfvars b/3-networks-svpc/access_context.auto.example.tfvars deleted file mode 100644 index 8f8871530..000000000 --- a/3-networks-svpc/access_context.auto.example.tfvars +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright 2021 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. - */ - -access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID diff --git a/3-networks-svpc/envs/development/README.md b/3-networks-svpc/envs/development/README.md index d69c834f0..65abc730b 100644 --- a/3-networks-svpc/envs/development/README.md +++ b/3-networks-svpc/envs/development/README.md @@ -15,7 +15,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -24,7 +23,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | diff --git a/3-networks-svpc/envs/development/main.tf b/3-networks-svpc/envs/development/main.tf index 6eaa2899f..61ee75789 100644 --- a/3-networks-svpc/envs/development/main.tf +++ b/3-networks-svpc/envs/development/main.tf @@ -48,7 +48,6 @@ module "base_env" { env = local.env environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain diff --git a/3-networks-svpc/envs/development/outputs.tf b/3-networks-svpc/envs/development/outputs.tf index 7abbe4f96..997e266de 100644 --- a/3-networks-svpc/envs/development/outputs.tf +++ b/3-networks-svpc/envs/development/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" diff --git a/3-networks-svpc/envs/development/variables.tf b/3-networks-svpc/envs/development/variables.tf index beab69a7b..a974988da 100644 --- a/3-networks-svpc/envs/development/variables.tf +++ b/3-networks-svpc/envs/development/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." diff --git a/3-networks-svpc/envs/nonproduction/README.md b/3-networks-svpc/envs/nonproduction/README.md index 1d147e226..41fe8a615 100644 --- a/3-networks-svpc/envs/nonproduction/README.md +++ b/3-networks-svpc/envs/nonproduction/README.md @@ -15,7 +15,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization | `string` | `""` | no | @@ -24,7 +23,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | diff --git a/3-networks-svpc/envs/nonproduction/main.tf b/3-networks-svpc/envs/nonproduction/main.tf index 81137c53f..5325d6bed 100644 --- a/3-networks-svpc/envs/nonproduction/main.tf +++ b/3-networks-svpc/envs/nonproduction/main.tf @@ -46,7 +46,6 @@ module "base_env" { env = local.env environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain diff --git a/3-networks-svpc/envs/nonproduction/outputs.tf b/3-networks-svpc/envs/nonproduction/outputs.tf index 7abbe4f96..997e266de 100644 --- a/3-networks-svpc/envs/nonproduction/outputs.tf +++ b/3-networks-svpc/envs/nonproduction/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" diff --git a/3-networks-svpc/envs/nonproduction/variables.tf b/3-networks-svpc/envs/nonproduction/variables.tf index beab69a7b..a974988da 100644 --- a/3-networks-svpc/envs/nonproduction/variables.tf +++ b/3-networks-svpc/envs/nonproduction/variables.tf @@ -19,11 +19,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." diff --git a/3-networks-svpc/envs/production/README.md b/3-networks-svpc/envs/production/README.md index 7f0b43dc9..b17c783f1 100644 --- a/3-networks-svpc/envs/production/README.md +++ b/3-networks-svpc/envs/production/README.md @@ -15,7 +15,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | target\_name\_server\_addresses | List of IPv4 address of target name servers for the forwarding zone configuration. See https://cloud.google.com/dns/docs/overview#dns-forwarding-zones for details on target name servers in the context of Cloud DNS forwarding zones. | `list(map(any))` | `[]` | no | @@ -25,7 +24,6 @@ The purpose of this step is to set up shared VPCs with default DNS, NAT (optiona | Name | Description | |------|-------------| -| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | network\_name | The name of the VPC being created | | network\_self\_link | The URI of the VPC being created | | shared\_vpc\_host\_project\_id | The shared vpc host project ID | diff --git a/3-networks-svpc/envs/production/main.tf b/3-networks-svpc/envs/production/main.tf index 86d273dee..bd833c3be 100644 --- a/3-networks-svpc/envs/production/main.tf +++ b/3-networks-svpc/envs/production/main.tf @@ -46,7 +46,6 @@ module "base_env" { env = local.env environment_code = local.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain diff --git a/3-networks-svpc/envs/production/outputs.tf b/3-networks-svpc/envs/production/outputs.tf index 7abbe4f96..997e266de 100644 --- a/3-networks-svpc/envs/production/outputs.tf +++ b/3-networks-svpc/envs/production/outputs.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -output "access_context_manager_policy_id" { - description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id -} - output "shared_vpc_host_project_id" { value = module.base_env.shared_vpc_host_project_id description = "The shared vpc host project ID" diff --git a/3-networks-svpc/envs/production/variables.tf b/3-networks-svpc/envs/production/variables.tf index 4746763fd..cbcd38e28 100644 --- a/3-networks-svpc/envs/production/variables.tf +++ b/3-networks-svpc/envs/production/variables.tf @@ -25,11 +25,6 @@ variable "remote_state_bucket" { type = string } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." diff --git a/3-networks-svpc/modules/base_env/README.md b/3-networks-svpc/modules/base_env/README.md index 9b6705e02..518f0821d 100644 --- a/3-networks-svpc/modules/base_env/README.md +++ b/3-networks-svpc/modules/base_env/README.md @@ -3,7 +3,6 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period. | `string` | n/a | yes | diff --git a/3-networks-svpc/modules/base_env/main.tf b/3-networks-svpc/modules/base_env/main.tf index 5d8c1ad5c..93b1d2c97 100644 --- a/3-networks-svpc/modules/base_env/main.tf +++ b/3-networks-svpc/modules/base_env/main.tf @@ -24,18 +24,17 @@ locals { module "shared_vpc" { source = "../shared_vpc" - project_id = local.shared_vpc_project_id - project_number = local.shared_vpc_project_number - dns_project_id = local.dns_project_id - environment_code = var.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - private_service_cidr = var.private_service_cidr - private_service_connect_ip = var.private_service_connect_ip - bgp_asn_subnet = local.bgp_asn_number - default_region1 = var.default_region1 - default_region2 = var.default_region2 - domain = var.domain - target_name_server_addresses = var.target_name_server_addresses + project_id = local.shared_vpc_project_id + project_number = local.shared_vpc_project_number + dns_project_id = local.dns_project_id + environment_code = var.environment_code + private_service_cidr = var.private_service_cidr + private_service_connect_ip = var.private_service_connect_ip + bgp_asn_subnet = local.bgp_asn_number + default_region1 = var.default_region1 + default_region2 = var.default_region2 + domain = var.domain + target_name_server_addresses = var.target_name_server_addresses diff --git a/3-networks-svpc/modules/base_env/variables.tf b/3-networks-svpc/modules/base_env/variables.tf index 0637807a6..0c1b65b6d 100644 --- a/3-networks-svpc/modules/base_env/variables.tf +++ b/3-networks-svpc/modules/base_env/variables.tf @@ -35,11 +35,6 @@ variable "environment_code" { description = "A short form of the folder level resources (environment) within the Google Cloud organization (ex. d)." } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy created in step `1-org`. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "default_region1" { type = string description = "First subnet region. The shared vpc modules only configures two regions." diff --git a/3-networks-svpc/modules/shared_vpc/README.md b/3-networks-svpc/modules/shared_vpc/README.md index 66fb953eb..76c8a30ee 100644 --- a/3-networks-svpc/modules/shared_vpc/README.md +++ b/3-networks-svpc/modules/shared_vpc/README.md @@ -3,7 +3,6 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `number` | n/a | yes | | bgp\_asn\_subnet | BGP ASN for Subnets cloud routers. | `number` | n/a | yes | | default\_region1 | First subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | diff --git a/3-networks-svpc/modules/shared_vpc/variables.tf b/3-networks-svpc/modules/shared_vpc/variables.tf index cbfb0f7b9..a5f6a2b69 100644 --- a/3-networks-svpc/modules/shared_vpc/variables.tf +++ b/3-networks-svpc/modules/shared_vpc/variables.tf @@ -25,11 +25,6 @@ variable "target_name_server_addresses" { type = list(map(any)) } -variable "access_context_manager_policy_id" { - type = number - description = "The id of the default Access Context Manager policy. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - variable "project_id" { type = string description = "Project ID for Shared VPC." From 001aae2e4e2e8cb50ab254758dae1990dd7c231e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 8 Aug 2025 17:47:26 -0300 Subject: [PATCH 049/114] fix lint --- 3-networks-svpc/envs/development/main.tf | 26 ++++++++++---------- 3-networks-svpc/envs/nonproduction/main.tf | 26 ++++++++++---------- 3-networks-svpc/envs/production/main.tf | 28 +++++++++++----------- 3 files changed, 40 insertions(+), 40 deletions(-) diff --git a/3-networks-svpc/envs/development/main.tf b/3-networks-svpc/envs/development/main.tf index 61ee75789..53713b601 100644 --- a/3-networks-svpc/envs/development/main.tf +++ b/3-networks-svpc/envs/development/main.tf @@ -46,17 +46,17 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.6" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.6" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-svpc/envs/nonproduction/main.tf b/3-networks-svpc/envs/nonproduction/main.tf index 5325d6bed..8dcc6afa4 100644 --- a/3-networks-svpc/envs/nonproduction/main.tf +++ b/3-networks-svpc/envs/nonproduction/main.tf @@ -44,17 +44,17 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_primary_ranges = local.subnet_primary_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.7" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_primary_ranges = local.subnet_primary_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.7" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name } diff --git a/3-networks-svpc/envs/production/main.tf b/3-networks-svpc/envs/production/main.tf index bd833c3be..57b04b5c0 100644 --- a/3-networks-svpc/envs/production/main.tf +++ b/3-networks-svpc/envs/production/main.tf @@ -44,18 +44,18 @@ locals { module "base_env" { source = "../../modules/base_env" - env = local.env - environment_code = local.environment_code - default_region1 = local.default_region1 - default_region2 = local.default_region2 - domain = var.domain - enable_partner_interconnect = false - private_service_cidr = local.private_service_cidr - subnet_primary_ranges = local.subnet_primary_ranges - subnet_proxy_ranges = local.subnet_proxy_ranges - subnet_secondary_ranges = local.subnet_secondary_ranges - private_service_connect_ip = "10.17.0.8" - remote_state_bucket = var.remote_state_bucket - tfc_org_name = var.tfc_org_name - target_name_server_addresses = var.target_name_server_addresses + env = local.env + environment_code = local.environment_code + default_region1 = local.default_region1 + default_region2 = local.default_region2 + domain = var.domain + enable_partner_interconnect = false + private_service_cidr = local.private_service_cidr + subnet_primary_ranges = local.subnet_primary_ranges + subnet_proxy_ranges = local.subnet_proxy_ranges + subnet_secondary_ranges = local.subnet_secondary_ranges + private_service_connect_ip = "10.17.0.8" + remote_state_bucket = var.remote_state_bucket + tfc_org_name = var.tfc_org_name + target_name_server_addresses = var.target_name_server_addresses } From c79999751110d7a7a8624bac7752a4a74517873b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 11 Aug 2025 18:23:12 -0300 Subject: [PATCH 050/114] update gcp-bootstrap pwd instructions --- 1-org/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/1-org/README.md b/1-org/README.md index 7c854ffcd..75e8763d7 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -280,7 +280,7 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu 1. Check if a Security Command Center notification with the default name, **scc-notify**, already exists. If it exists, choose a different value for the `scc_notification_name` variable in the `./envs/shared/terraform.tfvars` file. ```bash - export ORGANIZATION_ID=$(terraform -chdir="../gcp-bootstrap/" output -json common_config | jq '.org_id' --raw-output) + export ORGANIZATION_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared" output -json common_config | jq '.org_id' --raw-output) gcloud scc notifications describe "scc-notify" --organization=${ORGANIZATION_ID} ``` @@ -327,7 +327,7 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu 1. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export backend_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./envs/shared/terraform.tfvars @@ -342,10 +342,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, follow the [instruct 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from gcp-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw organization_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw organization_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` From 58158763d33b654b2b536d2e0627926ba8d96654 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 11 Aug 2025 18:26:15 -0300 Subject: [PATCH 051/114] add directional policies keys variables --- 1-org/envs/shared/README.md | 4 ++++ 1-org/envs/shared/service_control.tf | 8 ++++---- 1-org/envs/shared/variables.tf | 24 ++++++++++++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index ca460c78b..17bb0e9e0 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -12,6 +12,8 @@ | domains\_to\_allow | The list of domains to allow users from in IAM. Used by Domain Restricted Sharing Organization Policy. Must include the domain of the organization you are deploying the foundation. To add other domains you must also grant access to these domains to the Terraform Service Account used in the deploy. | `list(string)` | n/a | yes | | egress\_policies | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
external_resources = optional(list(string), [])
})
}))
| `[]` | no | | egress\_policies\_dry\_run | A list of all [egress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#egress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes egress\_from and egress\_to.

Example: `[{ from={ identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
external_resources = optional(list(string), [])
})
}))
| `[]` | no | +| egress\_policies\_keys | A list of keys to use for the Terraform state. The order should correspond to var.egress\_policies and the keys must not be dynamically computed. If `null`, var.egress\_policies will be used as keys. | `list(string)` | `[]` | no | +| egress\_policies\_keys\_dry\_run | (Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.egress\_policies\_dry\_run and the keys must not be dynamically computed. If `null`, var.egress\_policies\_dry\_run will be used as keys. | `list(string)` | `[]` | no | | enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_kms\_key\_usage\_tracking | Enable KMS centralized key usage tracking system. | `bool` | `true` | no | | enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. If your organization has newly enabled any preview features for SCC and get an error related to the v2 API, you must set this variable to false because the v2 API does not yet support Terraform resources. See [issue 1189](https://github.com/terraform-google-modules/terraform-example-foundation/issues/1189) for context. | `bool` | `false` | no | @@ -22,6 +24,8 @@ | gcp\_groups | Groups to grant specific roles in the Organization.
platform\_viewer: Google Workspace or Cloud Identity group that have the ability to view resource information across the Google Cloud organization.
security\_reviewer: Google Workspace or Cloud Identity group that members are part of the security team responsible for reviewing cloud security
network\_viewer: Google Workspace or Cloud Identity group that members are part of the networking team and review network configurations.
scc\_admin: Google Workspace or Cloud Identity group that can administer Security Command Center.
audit\_viewer: Google Workspace or Cloud Identity group that members are part of an audit team and view audit logs in the logging project.
global\_secrets\_admin: Google Workspace or Cloud Identity group that members are responsible for putting secrets into Secrets Management. |
object({
audit_viewer = optional(string, null)
security_reviewer = optional(string, null)
network_viewer = optional(string, null)
scc_admin = optional(string, null)
global_secrets_admin = optional(string, null)
kms_admin = optional(string, null)
})
| `{}` | no | | ingress\_policies | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
})
}))
| `[]` | no | | ingress\_policies\_dry\_run | A list of all [ingress policies](https://cloud.google.com/vpc-service-controls/docs/ingress-egress-rules#ingress-rules-reference) to use in a dry-run perimeter. Each list object has a `from` and `to` value that describes ingress\_from and ingress\_to.

Example: `[{ from={ sources={ resources=[], access_levels=[] }, identities=[], identity_type="ID_TYPE" }, to={ resources=[], operations={ "SRV_NAME"={ OP_TYPE=[] }}}}]`

Valid Values:
`ID_TYPE` = `null` or `IDENTITY_TYPE_UNSPECIFIED` (only allow indentities from list); `ANY_IDENTITY`; `ANY_USER_ACCOUNT`; `ANY_SERVICE_ACCOUNT`
`SRV_NAME` = "`*`" (allow all services) or [Specific Services](https://cloud.google.com/vpc-service-controls/docs/supported-products#supported_products)
`OP_TYPE` = [methods](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) or [permissions](https://cloud.google.com/vpc-service-controls/docs/supported-method-restrictions) |
list(object({
title = optional(string, null)
from = object({
sources = optional(object({
resources = optional(list(string), [])
access_levels = optional(list(string), [])
}), {}),
identity_type = optional(string, null)
identities = optional(list(string), null)
})
to = object({
operations = optional(map(object({
methods = optional(list(string), [])
permissions = optional(list(string), [])
})), {}),
roles = optional(list(string), null)
resources = optional(list(string), ["*"])
})
}))
| `[]` | no | +| ingress\_policies\_keys | A list of keys to use for the Terraform state. The order should correspond to var.ingress\_policies and the keys must not be dynamically computed. If `null`, var.ingress\_policies will be used as keys. | `list(string)` | `[]` | no | +| ingress\_policies\_keys\_dry\_run | (Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.ingress\_policies\_dry\_run and the keys must not be dynamically computed. If `null`, var.ingress\_policies\_dry\_run will be used as keys. | `list(string)` | `[]` | no | | log\_export\_storage\_force\_destroy | (Optional) If set to true, delete all contents when destroying the resource; otherwise, destroying the resource will fail if contents are present. | `bool` | `false` | no | | log\_export\_storage\_location | The location of the storage bucket used to export logs. | `string` | `null` | no | | log\_export\_storage\_retention\_policy | Configuration of the bucket's data retention policy for how long objects in the bucket should be retained. |
object({
is_locked = bool
retention_period_days = number
})
| `null` | no | diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 690d3e761..6fb0b6d0b 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -207,10 +207,10 @@ locals { [for p in local.projects : "${p}"] ) - ingress_policies_keys_dry_run = ["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"] - egress_policies_keys_dry_run = ["seed_to_cicd", "org_sa_to_scc"] - ingress_policies_keys = ["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"] - egress_policies_keys = ["seed_to_cicd", "org_sa_to_scc"] + ingress_policies_keys_dry_run = concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) + egress_policies_keys_dry_run = concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) + ingress_policies_keys = concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) + egress_policies_keys = concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) ingress_policies_dry_run_map = zipmap( local.ingress_policies_keys_dry_run, diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index c494ef8e0..09c1723a6 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -339,3 +339,27 @@ variable "resources_dry_run" { type = list(string) default = [] } + +variable "ingress_policies_keys" { + description = "A list of keys to use for the Terraform state. The order should correspond to var.ingress_policies and the keys must not be dynamically computed. If `null`, var.ingress_policies will be used as keys." + type = list(string) + default = [] +} + +variable "egress_policies_keys" { + description = "A list of keys to use for the Terraform state. The order should correspond to var.egress_policies and the keys must not be dynamically computed. If `null`, var.egress_policies will be used as keys." + type = list(string) + default = [] +} + +variable "ingress_policies_keys_dry_run" { + description = "(Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.ingress_policies_dry_run and the keys must not be dynamically computed. If `null`, var.ingress_policies_dry_run will be used as keys." + type = list(string) + default = [] +} + +variable "egress_policies_keys_dry_run" { + description = "(Dry-run) A list of keys to use for the Terraform state. The order should correspond to var.egress_policies_dry_run and the keys must not be dynamically computed. If `null`, var.egress_policies_dry_run will be used as keys." + type = list(string) + default = [] +} From 38ea3ea84f596c665144ec65e1f6cb21c74ffb24 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 11 Aug 2025 18:29:55 -0300 Subject: [PATCH 052/114] fix gcp-bootstrap pwd in READMES --- 2-environments/README.md | 6 +++--- 3-networks-hub-and-spoke/README.md | 6 +++--- 3-networks-svpc/README.md | 6 +++--- 4-projects/README.md | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/2-environments/README.md b/2-environments/README.md index a75598141..569ba657a 100644 --- a/2-environments/README.md +++ b/2-environments/README.md @@ -210,7 +210,7 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s 1. Use `terraform output` to get the backend bucket value from 0-bootstrap output. ```bash - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export backend_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./terraform.tfvars @@ -223,10 +223,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, please follow the [i 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from gcp-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw environment_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw environment_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` diff --git a/3-networks-hub-and-spoke/README.md b/3-networks-hub-and-spoke/README.md index 71aeda615..7edf310de 100644 --- a/3-networks-hub-and-spoke/README.md +++ b/3-networks-hub-and-spoke/README.md @@ -301,7 +301,7 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s 2. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. ```bash - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export backend_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars @@ -314,10 +314,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, please follow the [i 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw networks_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw networks_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` diff --git a/3-networks-svpc/README.md b/3-networks-svpc/README.md index 9ff610628..f541624b4 100644 --- a/3-networks-svpc/README.md +++ b/3-networks-svpc/README.md @@ -326,7 +326,7 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s 2. Use `terraform output` to get the backend bucket value from gcp-bootstrap output. ```bash - export backend_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export backend_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${backend_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars @@ -341,10 +341,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, please follow the [i 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw networks_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw networks_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` diff --git a/4-projects/README.md b/4-projects/README.md index 1c111b048..04271d4d5 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -337,7 +337,7 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s Use `terraform output` to get the remote state bucket (the backend bucket used by previous steps) value from `gcp-bootstrap` output. ```bash - export remote_state_bucket=$(terraform -chdir="../gcp-bootstrap/" output -raw gcs_bucket_tfstate) + export remote_state_bucket=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw gcs_bucket_tfstate) echo "remote_state_bucket = ${remote_state_bucket}" sed -i'' -e "s/REMOTE_STATE_BUCKET/${remote_state_bucket}/" ./common.auto.tfvars @@ -350,10 +350,10 @@ To use the `validate` option of the `tf-wrapper.sh` script, please follow the [i 1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from gcp-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/" output -raw seed_project_id) + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) echo ${SEED_PROJECT_ID} - export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/" output -raw projects_step_terraform_service_account_email) + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw projects_step_terraform_service_account_email) echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` From 879c02d423f34e14327222a230965b6a74b7bc9e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 12 Aug 2025 10:09:41 -0300 Subject: [PATCH 053/114] updt vpc-sc module version 7.1.3 --- 1-org/modules/service_control/main.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-org/modules/service_control/main.tf b/1-org/modules/service_control/main.tf index 629880fc4..b0c4a8fe0 100644 --- a/1-org/modules/service_control/main.tf +++ b/1-org/modules/service_control/main.tf @@ -27,7 +27,7 @@ resource "random_id" "random_access_level_suffix" { module "access_level" { source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 7.1.2" + version = "~> 7.1.3" description = "${local.prefix} Access Level for use in an enforced perimeter" policy = var.access_context_manager_policy_id @@ -37,7 +37,7 @@ module "access_level" { module "access_level_dry_run" { source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" - version = "~> 7.1.2" + version = "~> 7.1.3" description = "${local.prefix} Access Level for testing with a dry run perimeter" policy = var.access_context_manager_policy_id @@ -47,7 +47,7 @@ module "access_level_dry_run" { module "regular_service_perimeter" { source = "terraform-google-modules/vpc-service-controls/google//modules/regular_service_perimeter" - version = "~> 7.1.2" + version = "~> 7.1.3" policy = var.access_context_manager_policy_id perimeter_name = local.perimeter_name From 53961bc68fae15613e3982aa43f20b53901758f9 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 12 Aug 2025 14:07:23 -0300 Subject: [PATCH 054/114] add required ingress rules app infra variables flag --- 1-org/envs/shared/README.md | 2 + 1-org/envs/shared/service_control.tf | 110 ++++++++++++++++++++++++++- 1-org/envs/shared/variables.tf | 12 +++ 3 files changed, 122 insertions(+), 2 deletions(-) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 17bb0e9e0..8be80df58 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -35,6 +35,8 @@ | project\_budget | Budget configuration for projects.
budget\_amount: The amount to use as the budget.
alert\_spent\_percents: A list of percentages of the budget to alert on when threshold is exceeded.
alert\_pubsub\_topic: The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`.
alert\_spend\_basis: The type of basis used to determine if spend has passed the threshold. Possible choices are `CURRENT_SPEND` or `FORECASTED_SPEND` (default). |
object({
net_hub_budget_amount = optional(number, 1000)
net_hub_alert_spent_percents = optional(list(number), [1.2])
net_hub_alert_pubsub_topic = optional(string, null)
net_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
shared_network_budget_amount = optional(number, 1000)
shared_network_alert_spent_percents = optional(list(number), [1.2])
shared_network_alert_pubsub_topic = optional(string, null)
shared_network_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
interconnect_budget_amount = optional(number, 1000)
interconnect_alert_spent_percents = optional(list(number), [1.2])
interconnect_alert_pubsub_topic = optional(string, null)
interconnect_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_secrets_budget_amount = optional(number, 1000)
org_secrets_alert_spent_percents = optional(list(number), [1.2])
org_secrets_alert_pubsub_topic = optional(string, null)
org_secrets_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_billing_export_budget_amount = optional(number, 1000)
org_billing_export_alert_spent_percents = optional(list(number), [1.2])
org_billing_export_alert_pubsub_topic = optional(string, null)
org_billing_export_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_audit_logs_budget_amount = optional(number, 1000)
org_audit_logs_alert_spent_percents = optional(list(number), [1.2])
org_audit_logs_alert_pubsub_topic = optional(string, null)
org_audit_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
common_kms_budget_amount = optional(number, 1000)
common_kms_alert_spent_percents = optional(list(number), [1.2])
common_kms_alert_pubsub_topic = optional(string, null)
common_kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
scc_notifications_budget_amount = optional(number, 1000)
scc_notifications_alert_spent_percents = optional(list(number), [1.2])
scc_notifications_alert_pubsub_topic = optional(string, null)
scc_notifications_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
})
| `{}` | no | | project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | +| required\_ingress\_rules\_app\_infra | Required ingress rule app infra enforced mode. | `bool` | `false` | no | +| required\_ingress\_rules\_app\_infra\_dry\_run | Required ingress rule app infra dry run mode. | `bool` | `false` | no | | resources | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. | `list(string)` | `[]` | no | | resources\_dry\_run | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set. | `list(string)` | `[]` | no | | scc\_notification\_filter | Filter used to create the Security Command Center Notification, you can see more details on how to create filters in https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications#create-filter | `string` | `"state = \"ACTIVE\""` | no | diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 6fb0b6d0b..3a3dd9f13 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -405,6 +405,59 @@ locals { }, ] + required_ingress_rules_app_infra_dry_run = [ + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + "logging.googleapis.com" = { + methods = ["*"] + } + "iamcredentials.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + required_ingress_rules = [ { from = { @@ -529,6 +582,59 @@ locals { }, ] + required_ingress_rules_app_infra = [ + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + "logging.googleapis.com" = { + methods = ["*"] + } + "iamcredentials.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + required_egress_rules = [ { from = { @@ -603,8 +709,8 @@ module "service_control" { egress_policies_keys_dry_run = local.egress_policies_keys_dry_run ingress_policies_keys = local.ingress_policies_keys egress_policies_keys = local.egress_policies_keys_dry_run - ingress_policies = distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) - ingress_policies_dry_run = distinct(concat(values(local.ingress_policies_dry_run_map), var.ingress_policies_dry_run, local.required_ingress_rules_dry_run)) + ingress_policies = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, local.required_ingress_rules_app_infra, var.ingress_policies)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) + ingress_policies_dry_run = var.required_ingress_rules_app_infra_dry_run ? distinct(concat(values(local.ingress_policies_dry_run_map), local.required_ingress_rules_dry_run, local.required_ingress_rules_app_infra_dry_run, var.ingress_policies_dry_run)) : distinct(concat(values(local.ingress_policies_dry_run_map), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run, )) egress_policies = distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) egress_policies_dry_run = distinct(concat(values(local.egress_policies_dry_run_map), var.egress_policies_dry_run, local.required_egress_rules_dry_run)) diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index 09c1723a6..d47e23674 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -363,3 +363,15 @@ variable "egress_policies_keys_dry_run" { type = list(string) default = [] } + +variable "required_ingress_rules_app_infra" { + description = "Required ingress rule app infra enforced mode." + type = bool + default = false +} + +variable "required_ingress_rules_app_infra_dry_run" { + description = "Required ingress rule app infra dry run mode." + type = bool + default = false +} From b9fd55af84db4b35b318d0949e8423ad48355aea Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 12 Aug 2025 14:31:45 -0300 Subject: [PATCH 055/114] rm access_context_auto symbolic link --- .../envs/nonproduction/access_context.auto.tfvars | 1 - 3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars | 1 - 3-networks-svpc/envs/nonproduction/access_context.auto.tfvars | 1 - 3-networks-svpc/envs/production/access_context.auto.tfvars | 1 - 3-networks-svpc/envs/shared/access_context.auto.tfvars | 1 - 5 files changed, 5 deletions(-) delete mode 120000 3-networks-hub-and-spoke/envs/nonproduction/access_context.auto.tfvars delete mode 120000 3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars delete mode 120000 3-networks-svpc/envs/nonproduction/access_context.auto.tfvars delete mode 120000 3-networks-svpc/envs/production/access_context.auto.tfvars delete mode 120000 3-networks-svpc/envs/shared/access_context.auto.tfvars diff --git a/3-networks-hub-and-spoke/envs/nonproduction/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/nonproduction/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/nonproduction/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/shared/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/envs/nonproduction/access_context.auto.tfvars b/3-networks-svpc/envs/nonproduction/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/nonproduction/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/envs/production/access_context.auto.tfvars b/3-networks-svpc/envs/production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/envs/shared/access_context.auto.tfvars b/3-networks-svpc/envs/shared/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/shared/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file From dc31857a2c7b03cc0bfa74493663c66c53acd896 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 12 Aug 2025 16:07:20 -0300 Subject: [PATCH 056/114] fix data outputs and add org remote state --- 4-projects/modules/base_env/remote.tf | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/4-projects/modules/base_env/remote.tf b/4-projects/modules/base_env/remote.tf index 5624b7fa6..23a937955 100644 --- a/4-projects/modules/base_env/remote.tf +++ b/4-projects/modules/base_env/remote.tf @@ -19,12 +19,12 @@ locals { billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix projects_backend_bucket = data.terraform_remote_state.bootstrap.outputs.projects_gcs_bucket_tfstate - perimeter_name = data.terraform_remote_state.network_env.outputs.service_perimeter_name network_self_link = data.terraform_remote_state.network_env.outputs.network_self_link shared_vpc_host_project_id = data.terraform_remote_state.network_env.outputs.shared_vpc_host_project_id subnets_self_links = data.terraform_remote_state.network_env.outputs.subnets_self_links - access_context_manager_policy_id = data.terraform_remote_state.network_env.outputs.access_context_manager_policy_id - enforce_vpcsc = data.terraform_remote_state.network_env.outputs.enforce_vpcsc + access_context_manager_policy_id = data.terraform_remote_state.org.outputs.access_context_manager_policy_id + enforce_vpcsc = data.terraform_remote_state.org.outputs.enforce_vpcsc + perimeter_name = data.terraform_remote_state.org.outputs.service_perimeter_name env_folder_name = data.terraform_remote_state.environments_env.outputs.env_folder app_infra_pipeline_service_accounts = data.terraform_remote_state.business_unit_shared.outputs.terraform_service_accounts enable_cloudbuild_deploy = data.terraform_remote_state.business_unit_shared.outputs.enable_cloudbuild_deploy @@ -41,6 +41,15 @@ data "terraform_remote_state" "bootstrap" { } } +data "terraform_remote_state" "org_env" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/org/state" + } +} + data "terraform_remote_state" "network_env" { backend = "gcs" From 6659152ef6fff39c16eb60aaa016de1d131008a6 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 12 Aug 2025 16:14:17 -0300 Subject: [PATCH 057/114] add blank line --- 0-bootstrap/terraform.example.tfvars | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0-bootstrap/terraform.example.tfvars b/0-bootstrap/terraform.example.tfvars index 1efeefaa9..9b85c95fa 100644 --- a/0-bootstrap/terraform.example.tfvars +++ b/0-bootstrap/terraform.example.tfvars @@ -168,4 +168,4 @@ default_region_kms = "us" // For GitHub OAuth see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/github // For GitHub Enterprise see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/github-enterprise // For GitLab.com see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/gitlab-com -// For GitLab EE/CE see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/gitlab-eece \ No newline at end of file +// For GitLab EE/CE see: https://developer.hashicorp.com/terraform/cloud-docs/vcs/gitlab-eece From c0210814b9f44f77d44a1d75228a2ac66599321b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 13 Aug 2025 09:31:03 -0300 Subject: [PATCH 058/114] fix outputs remote.tf --- 4-projects/modules/base_env/remote.tf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/4-projects/modules/base_env/remote.tf b/4-projects/modules/base_env/remote.tf index 23a937955..17fa7632e 100644 --- a/4-projects/modules/base_env/remote.tf +++ b/4-projects/modules/base_env/remote.tf @@ -22,9 +22,9 @@ locals { network_self_link = data.terraform_remote_state.network_env.outputs.network_self_link shared_vpc_host_project_id = data.terraform_remote_state.network_env.outputs.shared_vpc_host_project_id subnets_self_links = data.terraform_remote_state.network_env.outputs.subnets_self_links - access_context_manager_policy_id = data.terraform_remote_state.org.outputs.access_context_manager_policy_id - enforce_vpcsc = data.terraform_remote_state.org.outputs.enforce_vpcsc - perimeter_name = data.terraform_remote_state.org.outputs.service_perimeter_name + access_context_manager_policy_id = data.terraform_remote_state.org_env.outputs.access_context_manager_policy_id + enforce_vpcsc = data.terraform_remote_state.org_env.outputs.enforce_vpcsc + perimeter_name = data.terraform_remote_state.org_env.outputs.service_perimeter_name env_folder_name = data.terraform_remote_state.environments_env.outputs.env_folder app_infra_pipeline_service_accounts = data.terraform_remote_state.business_unit_shared.outputs.terraform_service_accounts enable_cloudbuild_deploy = data.terraform_remote_state.business_unit_shared.outputs.enable_cloudbuild_deploy From 29f88dc57a4548db2935d04531bd00dc871b95a7 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 13 Aug 2025 10:39:23 -0300 Subject: [PATCH 059/114] add required egress rule app infra variables and intructions to set --- 1-org/README.md | 27 ---- 1-org/envs/shared/README.md | 4 +- 1-org/envs/shared/service_control.tf | 137 +++++----------- 1-org/envs/shared/terraform.example.tfvars | 4 + 1-org/envs/shared/variables.tf | 8 +- 4-projects/README.md | 180 ++++++--------------- 6 files changed, 103 insertions(+), 257 deletions(-) diff --git a/1-org/README.md b/1-org/README.md index 75e8763d7..17242ba9f 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -173,33 +173,6 @@ If required, run `terraform output cloudbuild_project_id` in the `0-bootstrap` f if [ ! -z "${ACCESS_CONTEXT_MANAGER_ID}" ]; then sed -i'' -e "s=//create_access_context_manager_access_policy=create_access_context_manager_access_policy=" ./envs/shared/terraform.tfvars; fi ``` -1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: - - ``` - { - from = { - identities = [ - "user:YOUR-USER-EMAIL@example.com", - ] - sources = { - resources = [ - "projects/${local.seed_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - ``` - 1. Run `terraform init` in `/envs/shared` to generate the outputs used in other steps. ```bash diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 8be80df58..5952946eb 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -35,8 +35,8 @@ | project\_budget | Budget configuration for projects.
budget\_amount: The amount to use as the budget.
alert\_spent\_percents: A list of percentages of the budget to alert on when threshold is exceeded.
alert\_pubsub\_topic: The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`.
alert\_spend\_basis: The type of basis used to determine if spend has passed the threshold. Possible choices are `CURRENT_SPEND` or `FORECASTED_SPEND` (default). |
object({
net_hub_budget_amount = optional(number, 1000)
net_hub_alert_spent_percents = optional(list(number), [1.2])
net_hub_alert_pubsub_topic = optional(string, null)
net_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
shared_network_budget_amount = optional(number, 1000)
shared_network_alert_spent_percents = optional(list(number), [1.2])
shared_network_alert_pubsub_topic = optional(string, null)
shared_network_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
interconnect_budget_amount = optional(number, 1000)
interconnect_alert_spent_percents = optional(list(number), [1.2])
interconnect_alert_pubsub_topic = optional(string, null)
interconnect_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_secrets_budget_amount = optional(number, 1000)
org_secrets_alert_spent_percents = optional(list(number), [1.2])
org_secrets_alert_pubsub_topic = optional(string, null)
org_secrets_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_billing_export_budget_amount = optional(number, 1000)
org_billing_export_alert_spent_percents = optional(list(number), [1.2])
org_billing_export_alert_pubsub_topic = optional(string, null)
org_billing_export_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_audit_logs_budget_amount = optional(number, 1000)
org_audit_logs_alert_spent_percents = optional(list(number), [1.2])
org_audit_logs_alert_pubsub_topic = optional(string, null)
org_audit_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
common_kms_budget_amount = optional(number, 1000)
common_kms_alert_spent_percents = optional(list(number), [1.2])
common_kms_alert_pubsub_topic = optional(string, null)
common_kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
scc_notifications_budget_amount = optional(number, 1000)
scc_notifications_alert_spent_percents = optional(list(number), [1.2])
scc_notifications_alert_pubsub_topic = optional(string, null)
scc_notifications_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
})
| `{}` | no | | project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | -| required\_ingress\_rules\_app\_infra | Required ingress rule app infra enforced mode. | `bool` | `false` | no | -| required\_ingress\_rules\_app\_infra\_dry\_run | Required ingress rule app infra dry run mode. | `bool` | `false` | no | +| required\_egress\_rules\_app\_infra | Required egress rule app infra enforced mode. | `bool` | `false` | no | +| required\_egress\_rules\_app\_infra\_dry\_run | Required egress rule app infra dry run mode. | `bool` | `false` | no | | resources | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. | `list(string)` | `[]` | no | | resources\_dry\_run | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set. | `list(string)` | `[]` | no | | scc\_notification\_filter | Filter used to create the Security Command Center Notification, you can see more details on how to create filters in https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications#create-filter | `string` | `"state = \"ACTIVE\""` | no | diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 3a3dd9f13..c5c3de9e1 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -279,6 +279,31 @@ locals { }, ] + required_egress_rules_app_infra_dry_run = [ + { + from = { + identities = [ + "serviceAccount:PRJ_APP_INFRA_PIPELINE_NUMBER@cloudbuild.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/PRJ_APP_INFRA_PIPELINE_NUMBER" + ] + } + } + to = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + operations = { + "cloudbuild.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + required_ingress_rules_dry_run = [ { from = { @@ -405,59 +430,6 @@ locals { }, ] - required_ingress_rules_app_infra_dry_run = [ - { - from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - "logging.googleapis.com" = { - methods = ["*"] - } - "iamcredentials.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.seed_project_number}" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - ] - required_ingress_rules = [ { from = { @@ -582,30 +554,24 @@ locals { }, ] - required_ingress_rules_app_infra = [ + required_egress_rules = [ { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", ] sources = { resources = [ - "projects/${local.cloudbuild_project_number}" + "projects/${local.seed_project_number}" ] } } to = { resources = [ - "projects/" + "projects/${local.cloudbuild_project_number}" ] operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - "logging.googleapis.com" = { - methods = ["*"] - } - "iamcredentials.googleapis.com" = { + "cloudbuild.googleapis.com" = { methods = ["*"] } } @@ -614,7 +580,7 @@ locals { { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", + "serviceAccount:${local.organization_service_account}", ] sources = { resources = [ @@ -624,10 +590,10 @@ locals { } to = { resources = [ - "projects/${local.seed_project_number}" + "projects/${module.scc_notifications.project_number}" ] operations = { - "storage.googleapis.com" = { + "cloudasset.googleapis.com" = { methods = ["*"] } } @@ -635,15 +601,15 @@ locals { }, ] - required_egress_rules = [ + required_egress_rules_app_infra = [ { from = { identities = [ - "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + "serviceAccount:PRJ_APP_INFRA_PIPELINE_NUMBER@cloudbuild.gserviceaccount.com", ] sources = { resources = [ - "projects/${local.seed_project_number}" + "projects/PRJ_APP_INFRA_PIPELINE_NUMBER" ] } } @@ -658,31 +624,10 @@ locals { } } }, - { - from = { - identities = [ - "serviceAccount:${local.organization_service_account}", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${module.scc_notifications.project_number}" - ] - operations = { - "cloudasset.googleapis.com" = { - methods = ["*"] - } - } - } - }, ] } + module "service_control" { source = "../../modules/service_control" @@ -709,10 +654,10 @@ module "service_control" { egress_policies_keys_dry_run = local.egress_policies_keys_dry_run ingress_policies_keys = local.ingress_policies_keys egress_policies_keys = local.egress_policies_keys_dry_run - ingress_policies = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, local.required_ingress_rules_app_infra, var.ingress_policies)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) - ingress_policies_dry_run = var.required_ingress_rules_app_infra_dry_run ? distinct(concat(values(local.ingress_policies_dry_run_map), local.required_ingress_rules_dry_run, local.required_ingress_rules_app_infra_dry_run, var.ingress_policies_dry_run)) : distinct(concat(values(local.ingress_policies_dry_run_map), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run, )) - egress_policies = distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) - egress_policies_dry_run = distinct(concat(values(local.egress_policies_dry_run_map), var.egress_policies_dry_run, local.required_egress_rules_dry_run)) + ingress_policies = distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) + ingress_policies_dry_run = distinct(concat(values(local.ingress_policies_dry_run_map), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run, )) + egress_policies = var.required_egress_rules_app_infra ? distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules, local.required_egress_rules_app_infra)) : distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) + egress_policies_dry_run = var.required_egress_rules_app_infra_dry_run ? distinct(concat(values(local.egress_policies_dry_run_map), var.egress_policies_dry_run, local.required_egress_rules_dry_run, local.required_egress_rules_app_infra_dry_run)) : distinct(concat(values(local.egress_policies_dry_run_map), var.egress_policies_dry_run, local.required_egress_rules_dry_run)) depends_on = [ time_sleep.wait_projects diff --git a/1-org/envs/shared/terraform.example.tfvars b/1-org/envs/shared/terraform.example.tfvars index 22356e0af..0e58225a7 100644 --- a/1-org/envs/shared/terraform.example.tfvars +++ b/1-org/envs/shared/terraform.example.tfvars @@ -45,3 +45,7 @@ billing_export_dataset_location = "US" //create_unique_tag_key = true access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID + +//required_egress_rules_app_infra_dry_run = true + +//required_egress_rules_app_infra = true diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index d47e23674..d31c8f3f2 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -364,14 +364,14 @@ variable "egress_policies_keys_dry_run" { default = [] } -variable "required_ingress_rules_app_infra" { - description = "Required ingress rule app infra enforced mode." +variable "required_egress_rules_app_infra" { + description = "Required egress rule app infra enforced mode." type = bool default = false } -variable "required_ingress_rules_app_infra_dry_run" { - description = "Required ingress rule app infra dry run mode." +variable "required_egress_rules_app_infra_dry_run" { + description = "Required egress rule app infra dry run mode." type = bool default = false } diff --git a/4-projects/README.md b/4-projects/README.md index 04271d4d5..4f126dabf 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -220,74 +220,35 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' git push origin nonproduction ``` -1. Use `terraform output` to get the APP Infra Pipeline Terraform service account. - - ```bash - export terraform_service_accounts=$(terraform -chdir="business_unit_1/shared/" output -json terraform_service_accounts | jq -r 'to_entries[0].value') - echo $terraform_service_accounts - ``` - -1. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: - - ``` - { - from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - "logging.googleapis.com" = { - methods = ["*"] - } - "iamcredentials.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.seed_project_number}" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - ``` - -1. Before executing the next step, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +1. Unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` +1. Use `terraform output` to get the APP Infra Pipeline cloud build project number. + + ```bash + export cloudbuild_project_number=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_number) + echo $cloudbuild_project_number + sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" ../gcp-org/envs/shared/service_control.tf + ``` + +1. Before executing the next stages, set `required_egress_rule_app_infra` and `required_egress_rule_app_infra_dry_run` variables in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. + + ```bash + cd ../gcp-org + git checkout production + + sed -i 's|^//\s*\(required_egress_rules_app_infra_dry_run\s*=.*\)|\1|' envs/shared/terraform.tfvars + sed -i 's|^//\s*\(required_egress_rules_app_infra\s*=.*\)|\1|' /envs/shared/terraform.tfvars + + git add envs/shared/terraform.tfvars + git commit -m "Add App Infra egress rule." + git push + cd ../ + ``` + 1. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. ### Deploying with Jenkins @@ -464,72 +425,35 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' cd ../ ``` -1. Use `terraform output` to get the APP Infra Pipeline Terraform service account. - - ```bash - export terraform_service_accounts=$(terraform -chdir="business_unit_1/shared/" output -json terraform_service_accounts | jq -r 'to_entries[0].value') - echo $terraform_service_accounts - ``` - -1. If you are deploying with VPC Service Controls in dry run mode, update the `required_ingres_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_ingres_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the directional rules: - - ``` - { - from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - "logging.googleapis.com" = { - methods = ["*"] - } - "iamcredentials.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.seed_project_number}" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, +If you received any errors or made any changes to the Terraform config or any `.tfvars`, you must re-run `./tf-wrapper.sh plan ` before run `./tf-wrapper.sh apply `. + +1. Unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. + + ```bash + unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT + ``` + +1. Use `terraform output` to get the APP Infra Pipeline cloud build project number. + + ```bash + export cloudbuild_project_number=$(terraform -chdir="gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_number) + echo $cloudbuild_project_number + sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" gcp-org/envs/shared/service_control.tf ``` -If you received any errors or made any changes to the Terraform config or any `.tfvars`, you must re-run `./tf-wrapper.sh plan ` before run `./tf-wrapper.sh apply `. +1. Before executing the next stages, set `required_egress_rule_app_infra` and `required_egress_rule_app_infra_dry_run` variables in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. + + ```bash + cd gcp-org + git checkout production -Before executing the next stages, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. + sed -i 's|^//\s*\(required_egress_rules_app_infra_dry_run\s*=.*\)|\1|' envs/shared/terraform.tfvars + sed -i 's|^//\s*\(required_egress_rules_app_infra\s*=.*\)|\1|' /envs/shared/terraform.tfvars -```bash -unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT -``` + ./tf-wrapper.sh plan production + ./tf-wrapper.sh apply production + + git add envs/shared/terraform.tfvars + git commit -m "Add App Infra egress rule." + cd ../ + ``` From 0a595d860c91d0af40d7271f91d12cc2cae036af Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 13 Aug 2025 14:34:57 -0300 Subject: [PATCH 060/114] change instructions 4-projects README --- 4-projects/README.md | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/4-projects/README.md b/4-projects/README.md index 4f126dabf..d0d8d36c7 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -228,20 +228,26 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' 1. Use `terraform output` to get the APP Infra Pipeline cloud build project number. + ```bash export cloudbuild_project_number=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_number) echo $cloudbuild_project_number sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" ../gcp-org/envs/shared/service_control.tf ``` -1. Before executing the next stages, set `required_egress_rule_app_infra` and `required_egress_rule_app_infra_dry_run` variables in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` variable to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` variable to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, and push your changes. ```bash cd ../gcp-org git checkout production - sed -i 's|^//\s*\(required_egress_rules_app_infra_dry_run\s*=.*\)|\1|' envs/shared/terraform.tfvars - sed -i 's|^//\s*\(required_egress_rules_app_infra\s*=.*\)|\1|' /envs/shared/terraform.tfvars + export enforce_vpcsc=$(terraform -chdir="envs/shared/" output -raw enforce_vpcsc); \ + echo "enforce_vpcsc" = $enforce_vpcsc + if [[ "$enforce_vpcsc" == "false" ]]; then \ + sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + else \ + sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + fi git add envs/shared/terraform.tfvars git commit -m "Add App Infra egress rule." @@ -457,3 +463,25 @@ If you received any errors or made any changes to the Terraform config or any `. git commit -m "Add App Infra egress rule." cd ../ ``` + +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` variable to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` variable to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, run `plan` and `apply`. + + ```bash + cd gcp-org + git checkout production + + export enforce_vpcsc=$(terraform -chdir="envs/shared/" output -raw enforce_vpcsc); \ + echo "enforce_vpcsc" = $enforce_vpcsc + if [[ "$enforce_vpcsc" == "false" ]]; then \ + sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + else \ + sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + fi + + ./tf-wrapper.sh plan production + ./tf-wrapper.sh apply production + + git add envs/shared/terraform.tfvars + git commit -m "Add App Infra egress rule." + cd ../ + ``` From 67f87a789bf81a7e6bb6f41dfb49055c0cfd595c Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 13 Aug 2025 16:22:02 -0300 Subject: [PATCH 061/114] fix README --- 4-projects/README.md | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/4-projects/README.md b/4-projects/README.md index d0d8d36c7..c1fdd2d95 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -447,24 +447,7 @@ If you received any errors or made any changes to the Terraform config or any `. sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" gcp-org/envs/shared/service_control.tf ``` -1. Before executing the next stages, set `required_egress_rule_app_infra` and `required_egress_rule_app_infra_dry_run` variables in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. - - ```bash - cd gcp-org - git checkout production - - sed -i 's|^//\s*\(required_egress_rules_app_infra_dry_run\s*=.*\)|\1|' envs/shared/terraform.tfvars - sed -i 's|^//\s*\(required_egress_rules_app_infra\s*=.*\)|\1|' /envs/shared/terraform.tfvars - - ./tf-wrapper.sh plan production - ./tf-wrapper.sh apply production - - git add envs/shared/terraform.tfvars - git commit -m "Add App Infra egress rule." - cd ../ - ``` - -1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` variable to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` variable to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, run `plan` and `apply`. +2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` variable to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` variable to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, run `plan` and `apply`. ```bash cd gcp-org From afbb1c27f1fa0843ac119208016dbf401ae3ccc0 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 10:21:21 -0300 Subject: [PATCH 062/114] add required ingress rules app infra --- 1-org/envs/shared/README.md | 2 + 1-org/envs/shared/service_control.tf | 187 +++++++++++++++++++-- 1-org/envs/shared/terraform.example.tfvars | 4 + 1-org/envs/shared/variables.tf | 12 ++ 4 files changed, 195 insertions(+), 10 deletions(-) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 5952946eb..5ea76f136 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -37,6 +37,8 @@ | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | required\_egress\_rules\_app\_infra | Required egress rule app infra enforced mode. | `bool` | `false` | no | | required\_egress\_rules\_app\_infra\_dry\_run | Required egress rule app infra dry run mode. | `bool` | `false` | no | +| required\_ingress\_rules\_app\_infra | Required ingress rule app infra enforced mode. | `bool` | `false` | no | +| required\_ingress\_rules\_app\_infra\_dry\_run | Required ingress rule app infra dry run mode. | `bool` | `false` | no | | resources | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. | `list(string)` | `[]` | no | | resources\_dry\_run | A list of GCP resources that are inside of the service perimeter. Currently only projects and VPC networks are allowed. If set, a dry-run policy will be set. | `list(string)` | `[]` | no | | scc\_notification\_filter | Filter used to create the Security Command Center Notification, you can see more details on how to create filters in https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications#create-filter | `string` | `"state = \"ACTIVE\""` | no | diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index c5c3de9e1..b3fbc2623 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -208,16 +208,16 @@ locals { ) ingress_policies_keys_dry_run = concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) - egress_policies_keys_dry_run = concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) + egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) ingress_policies_keys = concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) - egress_policies_keys = concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) + egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) - ingress_policies_dry_run_map = zipmap( + ingress_policies_map_dry_run = zipmap( local.ingress_policies_keys_dry_run, [for r in local.required_ingress_rules_dry_run : "${r}"] ) - egress_policies_dry_run_map = zipmap( + egress_policies_map_dry_run = zipmap( local.egress_policies_keys_dry_run, [for r in local.required_egress_rules_dry_run : "${r}"] ) @@ -227,10 +227,11 @@ locals { [for r in local.required_ingress_rules_dry_run : "${r}"] ) - egress_policies_map = zipmap( + egress_policies_map = var.required_egress_rules_app_infra ? zipmap( local.egress_policies_keys, - [for r in local.required_egress_rules_dry_run : "${r}"] - ) + [for r in concat(local.required_egress_rules_dry_run, local.required_egress_rules_app_infra) : "${r}"] + ) : zipmap(local.egress_policies_keys, + [for r in local.required_egress_rules_dry_run : "${r}"]) required_egress_rules_dry_run = [ { @@ -430,6 +431,89 @@ locals { }, ] + required_ingress_rules_app_infra_dry_run = [ + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/PRJ_BU1_APP_INFRA_NUMBER" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + "logging.googleapis.com" = { + methods = ["*"] + } + "iamcredentials.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/PRJS_DEV_SAMPLE_SVPC_NUMBER", + "projects/PRJS_DEV_SAMPLE_PEERING_NUMBER", + "projects/PRJS_PROD_SAMPLE_SVPC_NUMBER", + "projects/PRJS_PROD_SAMPLE_PEERING_NUMBER", + "projects/PRJS_NONPROD_SAMPLE_SVPC_NUMBER", + "projects/PRJS_NONPROD_SAMPLE_PEERING_NUMBER" + ] + operations = { + "iam.googleapis.com" = { + methods = ["*"] + } + "compute.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + required_ingress_rules = [ { from = { @@ -554,6 +638,89 @@ locals { }, ] + required_ingress_rules_app_infra = [ + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/PRJ_BU1_APP_INFRA_NUMBER" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + "logging.googleapis.com" = { + methods = ["*"] + } + "iamcredentials.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/PRJS_DEV_SAMPLE_SVPC_NUMBER", + "projects/PRJS_DEV_SAMPLE_PEERING_NUMBER", + "projects/PRJS_PROD_SAMPLE_SVPC_NUMBER", + "projects/PRJS_PROD_SAMPLE_PEERING_NUMBER", + "projects/PRJS_NONPROD_SAMPLE_SVPC_NUMBER", + "projects/PRJS_NONPROD_SAMPLE_PEERING_NUMBER" + ] + operations = { + "iam.googleapis.com" = { + methods = ["*"] + } + "compute.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + required_egress_rules = [ { from = { @@ -654,10 +821,10 @@ module "service_control" { egress_policies_keys_dry_run = local.egress_policies_keys_dry_run ingress_policies_keys = local.ingress_policies_keys egress_policies_keys = local.egress_policies_keys_dry_run - ingress_policies = distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) - ingress_policies_dry_run = distinct(concat(values(local.ingress_policies_dry_run_map), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run, )) + ingress_policies = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, local.required_ingress_rules_app_infra, var.ingress_policies)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) + ingress_policies_dry_run = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules, local.required_ingress_rules_app_infra_dry_run, var.ingress_policies_dry_run)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run)) egress_policies = var.required_egress_rules_app_infra ? distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules, local.required_egress_rules_app_infra)) : distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) - egress_policies_dry_run = var.required_egress_rules_app_infra_dry_run ? distinct(concat(values(local.egress_policies_dry_run_map), var.egress_policies_dry_run, local.required_egress_rules_dry_run, local.required_egress_rules_app_infra_dry_run)) : distinct(concat(values(local.egress_policies_dry_run_map), var.egress_policies_dry_run, local.required_egress_rules_dry_run)) + egress_policies_dry_run = var.required_egress_rules_app_infra_dry_run ? distinct(concat(values(local.egress_policies_map_dry_run), var.egress_policies_dry_run, local.required_egress_rules_dry_run, local.required_egress_rules_app_infra_dry_run)) : distinct(concat(values(local.egress_policies_map_dry_run), local.required_egress_rules_dry_run, var.egress_policies_dry_run)) depends_on = [ time_sleep.wait_projects diff --git a/1-org/envs/shared/terraform.example.tfvars b/1-org/envs/shared/terraform.example.tfvars index 0e58225a7..6d9e85f98 100644 --- a/1-org/envs/shared/terraform.example.tfvars +++ b/1-org/envs/shared/terraform.example.tfvars @@ -49,3 +49,7 @@ access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID //required_egress_rules_app_infra_dry_run = true //required_egress_rules_app_infra = true + +//required_ingress_rules_app_infra_dry_run = true + +//required_ingress_rules_app_infra = true \ No newline at end of file diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index d31c8f3f2..d074527e8 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -375,3 +375,15 @@ variable "required_egress_rules_app_infra_dry_run" { type = bool default = false } + +variable "required_ingress_rules_app_infra" { + description = "Required ingress rule app infra enforced mode." + type = bool + default = false +} + +variable "required_ingress_rules_app_infra_dry_run" { + description = "Required ingress rule app infra dry run mode." + type = bool + default = false +} From 136e1bb7b1ce275ce6b0cce56b0c2e932d17ff1c Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 10:32:26 -0300 Subject: [PATCH 063/114] add keys local ingress policies --- 1-org/envs/shared/service_control.tf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index b3fbc2623..373b7e6ac 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -207,9 +207,9 @@ locals { [for p in local.projects : "${p}"] ) - ingress_policies_keys_dry_run = concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) + ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed", "cicd_to_net_env"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) - ingress_policies_keys = concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) + ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed", "cicd_to_net_env"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) ingress_policies_map_dry_run = zipmap( From 2f7c32ed293ddddc1648d1cc52ff7b17ee1c07f0 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 10:48:10 -0300 Subject: [PATCH 064/114] add peering project number outputs --- 4-projects/business_unit_1/development/README.md | 1 + 4-projects/business_unit_1/development/outputs.tf | 5 +++++ 4-projects/modules/base_env/README.md | 1 + 4-projects/modules/base_env/outputs.tf | 5 +++++ 4 files changed, 12 insertions(+) diff --git a/4-projects/business_unit_1/development/README.md b/4-projects/business_unit_1/development/README.md index fd653c107..cec9febcb 100644 --- a/4-projects/business_unit_1/development/README.md +++ b/4-projects/business_unit_1/development/README.md @@ -27,6 +27,7 @@ | peering\_complete | Output to be used as a module dependency. | | peering\_network | Peer network peering resource. | | peering\_project | Project sample peering project id. | +| peering\_project\_number | Project sample shared vpc project. | | peering\_subnetwork\_self\_link | The subnetwork self link of the peering network. | | restricted\_enabled\_apis | Activated APIs. | | shared\_vpc\_project | Project sample shared vpc project id. | diff --git a/4-projects/business_unit_1/development/outputs.tf b/4-projects/business_unit_1/development/outputs.tf index f92ed8578..4be621231 100644 --- a/4-projects/business_unit_1/development/outputs.tf +++ b/4-projects/business_unit_1/development/outputs.tf @@ -24,6 +24,11 @@ output "peering_project" { value = module.env.peering_project } +output "peering_project_number" { + description = "Project sample shared vpc project." + value = module.env.peering_project_number +} + output "peering_network" { description = "Peer network peering resource." value = module.env.peering_network diff --git a/4-projects/modules/base_env/README.md b/4-projects/modules/base_env/README.md index ef2760eff..678dd9677 100644 --- a/4-projects/modules/base_env/README.md +++ b/4-projects/modules/base_env/README.md @@ -44,6 +44,7 @@ | peering\_complete | Output to be used as a module dependency. | | peering\_network | Peer network peering resource. | | peering\_project | Project sample peering project id. | +| peering\_project\_number | Project sample peering project number. | | peering\_subnetwork\_self\_link | The subnetwork self link of the peering network. | | restricted\_enabled\_apis | Activated APIs. | | shared\_vpc\_project | Project sample restricted project id. | diff --git a/4-projects/modules/base_env/outputs.tf b/4-projects/modules/base_env/outputs.tf index fa2f69d0b..4844cdf83 100644 --- a/4-projects/modules/base_env/outputs.tf +++ b/4-projects/modules/base_env/outputs.tf @@ -24,6 +24,11 @@ output "peering_project" { value = module.peering_project.project_id } +output "peering_project_number" { + description = "Project sample peering project number." + value = module.peering_project.project_number +} + output "peering_network" { description = "Peer network peering resource." value = module.peering.peer_network_peering From cfb26314d3a158c1831c56b2aeed7433f113c594 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 12:30:30 -0300 Subject: [PATCH 065/114] add required ingress rules ap infra instruction --- 4-projects/README.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/4-projects/README.md b/4-projects/README.md index c1fdd2d95..fdfb22378 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -235,7 +235,7 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" ../gcp-org/envs/shared/service_control.tf ``` -1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` variable to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` variable to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, and push your changes. +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` adn `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, and push your changes. ```bash cd ../gcp-org @@ -244,13 +244,18 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' export enforce_vpcsc=$(terraform -chdir="envs/shared/" output -raw enforce_vpcsc); \ echo "enforce_vpcsc" = $enforce_vpcsc if [[ "$enforce_vpcsc" == "false" ]]; then \ + sed -i -E '/^[[:space:]]*\/\/required_ingress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + else \ + sed -i -E '/^[[:space:]]*\/\/required_ingress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + fi + if [[ "$enforce_vpcsc" == "false" ]]; then \ sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ else \ sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ fi - + git add envs/shared/terraform.tfvars - git commit -m "Add App Infra egress rule." + git commit -m "Add App Infra directional rules." git push cd ../ ``` From 118277cda40512ec60861a04afb4026a57ea1dd2 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 14:02:46 -0300 Subject: [PATCH 066/114] fix lint --- 4-projects/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/4-projects/README.md b/4-projects/README.md index fdfb22378..e87653bc8 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -253,7 +253,7 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' else \ sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ fi - + git add envs/shared/terraform.tfvars git commit -m "Add App Infra directional rules." git push From 8d21c8972044ed9a7cab2a0e6af7382e0cb288d3 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 15:46:51 -0300 Subject: [PATCH 067/114] add VPC SC troubleshooting --- docs/TROUBLESHOOTING.md | 131 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 12 deletions(-) diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 52584d045..1a7116e99 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -12,23 +12,34 @@ See [GLOSSARY.md](./GLOSSARY.md). - [Caller does not have permission in the Organization](#caller-does-not-have-permission-in-the-organization) - [Billing quota exceeded](#billing-quota-exceeded) - [Terraform Error acquiring the state lock](#terraform-error-acquiring-the-state-lock) +- [VPC Service Controls](#vpc-service-controls) - - - ## Common issues -- [Project quota exceeded](#project-quota-exceeded) -- [Default branch setting](#default-branch-setting) -- [Terraform State Snapshot lock](#terraform-state-snapshot-lock) -- [Application authenticated using end user credentials](#application-authenticated-using-end-user-credentials) -- [Cannot assign requested address error in Cloud Shell](#cannot-assign-requested-address-error-in-cloud-shell) -- [Error: Unsupported attribute](#error-unsupported-attribute) -- [Error: Error adding network peering](#error-error-adding-network-peering) -- [Error: Terraform deploy fails due to GitLab repositories not found](#terraform-deploy-fails-due-to-gitlab-repositories-not-found) -- [Error: Gitlab pipelines access denied](#gitlab-pipelines-access-denied) -- [Error: Unknown project id on 4-project step context](#error-unknown-project-id-on-4-project-step-context) -- [Error: Error getting operation for committing purpose for TagValue](#error-error-getting-operation-for-committing-purpose-for-tagvalue) -- [The user does not have permission to access Project or it may not exist](#the-user-does-not-have-permission-to-access-project-or-it-may-not-exist) +- [Troubleshooting](#troubleshooting) + - [Terminology](#terminology) + - [Problems](#problems) + - [Common issues](#common-issues) + - [Project quota exceeded](#project-quota-exceeded) + - [Default branch setting](#default-branch-setting) + - [Terraform State Snapshot lock](#terraform-state-snapshot-lock) + - [Downgrade your local Terraform version](#downgrade-your-local-terraform-version) + - [Upgrade your 0-bootstrap runner image Terraform version](#upgrade-your-0-bootstrap-runner-image-terraform-version) + - [Application authenticated using end user credentials](#application-authenticated-using-end-user-credentials) + - [Cannot assign requested address error in Cloud Shell](#cannot-assign-requested-address-error-in-cloud-shell) + - [Error: Unsupported attribute](#error-unsupported-attribute) + - [Error: Error adding network peering](#error-error-adding-network-peering) + - [Error: Unknown project id on 4-project step context](#error-unknown-project-id-on-4-project-step-context) + - [Error: Error getting operation for committing purpose for TagValue](#error-error-getting-operation-for-committing-purpose-for-tagvalue) + - [Caller does not have permission in the Organization](#caller-does-not-have-permission-in-the-organization) + - [Billing quota exceeded](#billing-quota-exceeded) + - [Terraform Error acquiring the state lock](#terraform-error-acquiring-the-state-lock) + - [VPC Service Controls](#vpc-service-controls) + - [Terraform deploy fails due to GitLab repositories not found](#terraform-deploy-fails-due-to-gitlab-repositories-not-found) + - [Gitlab pipelines access denied](#gitlab-pipelines-access-denied) + - [The user does not have permission to access Project or it may not exist](#the-user-does-not-have-permission-to-access-project-or-it-may-not-exist) - - - ### Project quota exceeded @@ -495,6 +506,102 @@ You can get this information from step `0-bootstrap` by running the following co - If you realize that the Terraform State lock was due to a build timeout increase the build timeout on [build configuration](https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/build/cloudbuild-tf-apply.yaml#L15). +### VPC Service Controls + +**Error message:** + +```text +Failed to load state: Failed to open state file at gs://YOUR-TF-STATE-BUCKET/terraform/bootstrap/state/default.tfstate: googleapi: got HTTP response code 403 with body: SecurityPolicyViolatedRequest violates VPC Service Controls.
Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier: VPC-UNIQUE-IDENTIFIER
+``` + +**Cause:** + +You are trying to access an output from a Terraform remote state stored in a project that is inside a VPC Service Controls perimeter. However, your current environment is configured with a billing/quota_project that is not part of that perimeter. Since the VPC Service Controls perimeter is in enforced mode, this configuration blocks access. + +**Solution:** + +Run the following gcloud commands to remove the configured billing/quota_project from your environment: + + ```bash + gcloud config unset billing/quota_project + gcloud auth application-default login + ``` + +This will ensure that requests are not made using the billing/quota_project configured in your environment, which is outside the VPC Service Controls perimeter and causes access to be blocked. + +If you must use a billing/quota_project outside the perimeter, you will need to add the following egress rule using the `egress_policies` variable for VPC Service Controls in enforced mode in the `1-org/envs/shared/terraform.tfvars` + +Steps: + +1. Navigate into the [gcp-org/envs/shared/terraform.tfvars](gcp-org/envs/shared/terraform.tfvars) and change to the `production` branch: + + ```bash + cd gcp-org/envs/shared/ + git checkout production + ``` + +- Update `egress_policies` variable, with the following rule: + + ``` + { + from = { + identities = [ + "user:YOUR-USER-EMAIL@example.com", + ] + sources = { + resources = [ + "projects/SEED_PROJECT_NUMBER" + ] + } + } + to = { + resources = [ + "projects/YOUR_BILLING_QUOTA_PROJECT" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ``` + +- Update the `egress_policies_keys` variable with the `"seed_to_billing_prj"` value. +- Update the identities field to match the values of the `perimeter_additional_members variable`. +- Run the following command to get the Seed project number and the Billing project configured in your environment project number. + + ```bash + export seed_project_number=$(terraform -chdir="../../../gcp-bootstrap/envs/shared/" output -raw seed_project_number) + echo "seed_project_number = ${seed_project_number}" + + export billing_quota_project_number=$(gcloud projects describe "$(gcloud config get-value billing/quota_project)" --format="value(projectNumber)") + echo "billing_quota_project_number = ${billing_quota_project_number}" + + sed -i'' -e "s/SEED_PROJECT_NUMBER/${seed_project_number}/" ./terraform.tfvars + sed -i'' -e "s/YOUR_BILLING_QUOTA_PROJECT/${billing_quota_project_number}/" ./terraform.tfvars + ``` + +- Use `terraform output` to get an environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +- Run `init`, `plan` and `apply` and review the output. +- Commit validated code. + + ```bash + cd ../../ + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw organization_step_terraform_service_account_email) + echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} + + ./tf-wrapper.sh init production + ./tf-wrapper.sh plan production + ./tf-wrapper.sh apply production + + git add . + git commit -m "Add egress rule for billig/quota project." + cd .. + + unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT + ``` + ### Terraform deploy fails due to GitLab repositories not found **Error message:** From 6cc1ea5961d2b2f7350473167a9319d0b7b7a947 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 15:48:28 -0300 Subject: [PATCH 068/114] fix lint --- docs/TROUBLESHOOTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index 1a7116e99..9cb4d0664 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -570,7 +570,7 @@ Steps: - Update the `egress_policies_keys` variable with the `"seed_to_billing_prj"` value. - Update the identities field to match the values of the `perimeter_additional_members variable`. - Run the following command to get the Seed project number and the Billing project configured in your environment project number. - + ```bash export seed_project_number=$(terraform -chdir="../../../gcp-bootstrap/envs/shared/" output -raw seed_project_number) echo "seed_project_number = ${seed_project_number}" @@ -599,7 +599,7 @@ Steps: git commit -m "Add egress rule for billig/quota project." cd .. - unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT + unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` ### Terraform deploy fails due to GitLab repositories not found From eb7df3d3e8d3f859b02fbd23ade817dfe2efd5d5 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 14 Aug 2025 21:40:03 -0300 Subject: [PATCH 069/114] rm cai monitoring output --- 1-org/envs/shared/outputs.tf | 5 ----- 1 file changed, 5 deletions(-) diff --git a/1-org/envs/shared/outputs.tf b/1-org/envs/shared/outputs.tf index 51e80fa67..6ac9d6dab 100644 --- a/1-org/envs/shared/outputs.tf +++ b/1-org/envs/shared/outputs.tf @@ -149,11 +149,6 @@ output "cai_monitoring_topic" { description = "CAI Monitoring Cloud Function Pub/Sub Topic name." } -output "build_service_account" { - description = "Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container." - value = google_service_account.cai_monitoring_builder[0].email -} - output "enforce_vpcsc" { value = module.service_control.enforce_vpcsc description = "The mode of VPC Service Controls." From 31f094abf840951fb51dccc14b4db19a1191fd41 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 18 Aug 2025 10:08:38 -0300 Subject: [PATCH 070/114] rm access context file --- 1-org/envs/shared/README.md | 1 - .../envs/development/access_context.auto.tfvars | 1 - .../envs/production/access_context.auto.tfvars | 1 - 3-networks-svpc/envs/development/access_context.auto.tfvars | 1 - 4 files changed, 4 deletions(-) delete mode 120000 3-networks-hub-and-spoke/envs/development/access_context.auto.tfvars delete mode 120000 3-networks-hub-and-spoke/envs/production/access_context.auto.tfvars delete mode 120000 3-networks-svpc/envs/development/access_context.auto.tfvars diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 5ea76f136..e9a9e2538 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -53,7 +53,6 @@ | access\_level\_name | Access context manager access level name | | access\_level\_name\_dry\_run | Access context manager access level name for the dry-run perimeter | | billing\_sink\_names | The name of the sinks under billing account level. | -| build\_service\_account | Cloud Function Build Service Account Id. This is The fully-qualified name of the service account to be used for building the container. | | cai\_monitoring\_artifact\_registry | CAI Monitoring Cloud Function Artifact Registry name. | | cai\_monitoring\_asset\_feed | CAI Monitoring Cloud Function Organization Asset Feed name. | | cai\_monitoring\_bucket | CAI Monitoring Cloud Function Source Bucket name. | diff --git a/3-networks-hub-and-spoke/envs/development/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/development/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/development/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-hub-and-spoke/envs/production/access_context.auto.tfvars b/3-networks-hub-and-spoke/envs/production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-hub-and-spoke/envs/production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/3-networks-svpc/envs/development/access_context.auto.tfvars b/3-networks-svpc/envs/development/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/3-networks-svpc/envs/development/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file From b7bc940a90b4aa7e71a1836e603e272367ca753f Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 18 Aug 2025 13:10:57 -0300 Subject: [PATCH 071/114] fix syntax --- 0-bootstrap/README-GitHub.md | 2 +- 0-bootstrap/README-GitLab.md | 2 +- 3-networks-svpc/README.md | 2 +- 4-projects/README.md | 8 +++++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/0-bootstrap/README-GitHub.md b/0-bootstrap/README-GitHub.md index db5be2592..eb2571fea 100644 --- a/0-bootstrap/README-GitHub.md +++ b/0-bootstrap/README-GitHub.md @@ -665,7 +665,7 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th 1. Push your production branch since development and nonproduction depends it. -*Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. +*Note:** The Production environment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. ```bash git add . diff --git a/0-bootstrap/README-GitLab.md b/0-bootstrap/README-GitLab.md index ff3207693..1b5a4d205 100644 --- a/0-bootstrap/README-GitLab.md +++ b/0-bootstrap/README-GitLab.md @@ -668,7 +668,7 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th 1. Push your production branch since development and nonproduction depends it. -*Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. +*Note:** The Production environment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. ```bash git add . diff --git a/3-networks-svpc/README.md b/3-networks-svpc/README.md index f541624b4..519f017ed 100644 --- a/3-networks-svpc/README.md +++ b/3-networks-svpc/README.md @@ -233,7 +233,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get 14. Push your production branch since development and nonproduction depends it. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID -*Note:** The Production envrionment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. +*Note:** The Production environment must be the first branch to be pushed as it includes the DNS Hub communication that will be used by other environments. ```bash git push --set-upstream origin production diff --git a/4-projects/README.md b/4-projects/README.md index e87653bc8..2268fb0dd 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -226,20 +226,22 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -1. Use `terraform output` to get the APP Infra Pipeline cloud build project number. +1. Use `terraform output` to get the APP Infra Pipeline cloud build project id and project number. ```bash export cloudbuild_project_number=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_number) - echo $cloudbuild_project_number + echo "cloud build project number = $cloudbuild_project_number" + export cloudbuild_project_id=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_id) + echo "cloud build project id = $cloudbuild_project_id" sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" ../gcp-org/envs/shared/service_control.tf + sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" ../gcp-org/envs/shared/service_control.tf ``` 1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` adn `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, and push your changes. ```bash cd ../gcp-org - git checkout production export enforce_vpcsc=$(terraform -chdir="envs/shared/" output -raw enforce_vpcsc); \ echo "enforce_vpcsc" = $enforce_vpcsc From 4dd750c7b7f2365117b55988dc1842733dcba936 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 18 Aug 2025 13:14:39 -0300 Subject: [PATCH 072/114] fix replace --- 1-org/envs/shared/service_control.tf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 373b7e6ac..d580ac860 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -435,7 +435,7 @@ locals { { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", ] sources = { resources = [ @@ -463,7 +463,7 @@ locals { { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", ] sources = { resources = [ @@ -485,7 +485,7 @@ locals { { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", ] sources = { resources = [ @@ -642,7 +642,7 @@ locals { { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", ] sources = { resources = [ @@ -670,7 +670,7 @@ locals { { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", ] sources = { resources = [ @@ -692,7 +692,7 @@ locals { { from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_BU1_APP_INFRA_ID.iam.gserviceaccount.com", + "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", ] sources = { resources = [ From 058c13e93bb9d3961177a618d0b67ba0318e48cf Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 18 Aug 2025 14:34:53 -0300 Subject: [PATCH 073/114] add peering project number outputs --- 1-org/envs/shared/service_control.tf | 31 ++++++++++--------- .../business_unit_1/nonproduction/README.md | 1 + .../business_unit_1/nonproduction/outputs.tf | 5 +++ .../business_unit_1/production/README.md | 1 + .../business_unit_1/production/outputs.tf | 5 +++ 5 files changed, 29 insertions(+), 14 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index d580ac860..5dc051f31 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -207,31 +207,34 @@ locals { [for p in local.projects : "${p}"] ) - ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed", "cicd_to_net_env"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) + ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) - ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed", "cicd_to_net_env"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) + ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) - ingress_policies_map_dry_run = zipmap( + ingress_policies_map_dry_run = var.required_ingress_rules_app_infra_dry_run ? zipmap( local.ingress_policies_keys_dry_run, - [for r in local.required_ingress_rules_dry_run : "${r}"] - ) + [for r in concat(local.required_ingress_rules_dry_run, local.required_ingress_rules_app_infra_dry_run) : "${r}"] + ) : zipmap(local.ingress_policies_keys_dry_run, + [for r in local.required_ingress_rules_dry_run : "${r}"]) - egress_policies_map_dry_run = zipmap( + egress_policies_map_dry_run = var.required_egress_rules_app_infra_dry_run ? zipmap( local.egress_policies_keys_dry_run, - [for r in local.required_egress_rules_dry_run : "${r}"] - ) + [for r in concat(local.required_egress_rules_dry_run, local.required_egress_rules_app_infra_dry_run) : "${r}"] + ) : zipmap(local.egress_policies_keys_dry_run, + [for r in local.required_egress_rules_dry_run : "${r}"]) - ingress_policies_map = zipmap( + ingress_policies_map = var.required_ingress_rules_app_infra ? zipmap( local.ingress_policies_keys, - [for r in local.required_ingress_rules_dry_run : "${r}"] - ) + [for r in concat(local.required_ingress_rules, local.required_ingress_rules_app_infra) : "${r}"] + ) : zipmap(local.ingress_policies_keys, + [for r in local.required_ingress_rules : "${r}"]) egress_policies_map = var.required_egress_rules_app_infra ? zipmap( local.egress_policies_keys, - [for r in concat(local.required_egress_rules_dry_run, local.required_egress_rules_app_infra) : "${r}"] + [for r in concat(local.required_egress_rules, local.required_egress_rules_app_infra) : "${r}"] ) : zipmap(local.egress_policies_keys, - [for r in local.required_egress_rules_dry_run : "${r}"]) + [for r in local.required_egress_rules : "${r}"]) required_egress_rules_dry_run = [ { @@ -822,7 +825,7 @@ module "service_control" { ingress_policies_keys = local.ingress_policies_keys egress_policies_keys = local.egress_policies_keys_dry_run ingress_policies = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, local.required_ingress_rules_app_infra, var.ingress_policies)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) - ingress_policies_dry_run = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules, local.required_ingress_rules_app_infra_dry_run, var.ingress_policies_dry_run)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run)) + ingress_policies_dry_run = var.required_ingress_rules_app_infra_dry_run ? distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules_dry_run, local.required_ingress_rules_app_infra_dry_run, var.ingress_policies_dry_run)) : distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run)) egress_policies = var.required_egress_rules_app_infra ? distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules, local.required_egress_rules_app_infra)) : distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) egress_policies_dry_run = var.required_egress_rules_app_infra_dry_run ? distinct(concat(values(local.egress_policies_map_dry_run), var.egress_policies_dry_run, local.required_egress_rules_dry_run, local.required_egress_rules_app_infra_dry_run)) : distinct(concat(values(local.egress_policies_map_dry_run), local.required_egress_rules_dry_run, var.egress_policies_dry_run)) diff --git a/4-projects/business_unit_1/nonproduction/README.md b/4-projects/business_unit_1/nonproduction/README.md index e0ff4ea94..aa1af1107 100644 --- a/4-projects/business_unit_1/nonproduction/README.md +++ b/4-projects/business_unit_1/nonproduction/README.md @@ -27,6 +27,7 @@ | peering\_complete | Output to be used as a module dependency. | | peering\_network | Peer network peering resource. | | peering\_project | Project sample peering project id. | +| peering\_project\_number | Project sample shared vpc project. | | peering\_subnetwork\_self\_link | The subnetwork self link of the peering network. | | restricted\_enabled\_apis | Activated APIs. | | shared\_vpc\_project | Project sample project id. | diff --git a/4-projects/business_unit_1/nonproduction/outputs.tf b/4-projects/business_unit_1/nonproduction/outputs.tf index 120ff0ad1..eb85ba83e 100644 --- a/4-projects/business_unit_1/nonproduction/outputs.tf +++ b/4-projects/business_unit_1/nonproduction/outputs.tf @@ -24,6 +24,11 @@ output "peering_project" { value = module.env.peering_project } +output "peering_project_number" { + description = "Project sample shared vpc project." + value = module.env.peering_project_number +} + output "peering_network" { description = "Peer network peering resource." value = module.env.peering_network diff --git a/4-projects/business_unit_1/production/README.md b/4-projects/business_unit_1/production/README.md index d8cb23985..2df80510d 100644 --- a/4-projects/business_unit_1/production/README.md +++ b/4-projects/business_unit_1/production/README.md @@ -27,6 +27,7 @@ | peering\_complete | Output to be used as a module dependency. | | peering\_network | Peer network peering resource. | | peering\_project | Project sample peering project id. | +| peering\_project\_number | Project sample shared vpc project. | | peering\_subnetwork\_self\_link | The subnetwork self link of the peering network. | | restricted\_enabled\_apis | Activated APIs. | | shared\_vpc\_project | Project sample shared vpc project id. | diff --git a/4-projects/business_unit_1/production/outputs.tf b/4-projects/business_unit_1/production/outputs.tf index 0cd227d6a..a4bc488f1 100644 --- a/4-projects/business_unit_1/production/outputs.tf +++ b/4-projects/business_unit_1/production/outputs.tf @@ -24,6 +24,11 @@ output "peering_project" { value = module.env.peering_project } +output "peering_project_number" { + description = "Project sample shared vpc project." + value = module.env.peering_project_number +} + output "peering_network" { description = "Peer network peering resource." value = module.env.peering_network From da02dc278af9d3d6b2dce410b6cd5b87744df0e2 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 18 Aug 2025 15:31:51 -0300 Subject: [PATCH 074/114] Updt 1-org README and fix 4-projects README directional policies app infra --- 1-org/README.md | 27 -------- 4-projects/README.md | 154 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 133 insertions(+), 48 deletions(-) diff --git a/1-org/README.md b/1-org/README.md index 17242ba9f..647fd0fe2 100644 --- a/1-org/README.md +++ b/1-org/README.md @@ -270,33 +270,6 @@ Create `gcp-org` folder, copy `1-org` content and Terraform wrapper script; ensu sed -i'' -e "s/ACCESS_CONTEXT_MANAGER_ID/${ACCESS_CONTEXT_MANAGER_ID}/" ./envs/shared/terraform.tfvars ``` -1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rules_dry_run` list, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rules` list, in [gcp-org/envs/shared/service_control.tf](../gcp-org/envs/shared/service_control.tf) with the same value as your user that you updated in `envs/shared/terraform.tfvars`: - - ``` - { - from = { - identities = [ - "user:YOUR-USER-EMAIL@example.com", - ] - sources = { - resources = [ - "projects/${local.seed_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - ``` - 1. Update the `envs/shared/terraform.tfvars` file with values from your environment and `gcp-bootstrap` step. If the previous step showed a numeric value, un-comment the variable `create_access_context_manager_access_policy = false`. See the shared folder [README.md](./envs/shared/README.md) for additional information on the values in the `terraform.tfvars` file. ```bash diff --git a/4-projects/README.md b/4-projects/README.md index 2268fb0dd..57854218b 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -226,23 +226,62 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -1. Use `terraform output` to get the APP Infra Pipeline cloud build project id and project number. +1. Before move to the next step, configure directional policies for your perimeter. +1. Use `terraform output` to get the APP Infra Pipeline cloud build project id and project number. ```bash + cd ../gcp-org + export cloudbuild_project_number=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_number) echo "cloud build project number = $cloudbuild_project_number" export cloudbuild_project_id=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_id) echo "cloud build project id = $cloudbuild_project_id" - sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" ../gcp-org/envs/shared/service_control.tf - sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" ../gcp-org/envs/shared/service_control.tf + sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" /envs/shared/service_control.tf + sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" /envs/shared/service_control.tf ``` -1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` adn `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, and push your changes. +1. Use `terraform output` to get the Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project. +1. Use `gsutil cat` to get the project numbers of the SVPC and Peering projects in each environment (production, nonproduction, and development) for configuring the directional app infra policies. ```bash - cd ../gcp-org + export projects_gcs_bucket_tfstate=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw projects_gcs_bucket_tfstate) + echo "projects_gcs_bucket_tfstate = ${projects_gcs_bucket_tfstate}" + + export peering_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_dev = ${peering_project_number_dev}" + sed -i'' -e "s/PRJS_DEV_SAMPLE_PEERING_NUMBER/${peering_project_number_dev}/" envs/shared/service_control.tf + + export peering_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_prod = ${peering_project_number_prod}" + sed -i'' -e "s/PRJS_PROD_SAMPLE_PEERING_NUMBER/${peering_project_number_prod}/" envs/shared/service_control.tf + + export peering_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_nonprod = ${peering_project_number_nonprod}" + sed -i'' -e "s/PRJS_NONPROD_SAMPLE_PEERING_NUMBER/${peering_project_number_nonprod}/" envs/shared/service_control.tf + + export shared_vpc_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_dev = ${shared_vpc_project_number_dev}" + sed -i'' -e "s/PRJS_DEV_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_dev}/" /envs/shared/service_control.tf + export shared_vpc_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_prod = ${shared_vpc_project_number_prod}" + sed -i'' -e "s/PRJS_PROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_prod}/" /envs/shared/service_control.tf + + export shared_vpc_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_nonprod = ${shared_vpc_project_number_nonprod}" + sed -i'' -e "s/PRJS_NONPROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_nonprod}/" /envs/shared/service_control.tf + ``` + +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` and `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. + + ```bash export enforce_vpcsc=$(terraform -chdir="envs/shared/" output -raw enforce_vpcsc); \ echo "enforce_vpcsc" = $enforce_vpcsc if [[ "$enforce_vpcsc" == "false" ]]; then \ @@ -255,11 +294,16 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' else \ sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ fi + ``` - git add envs/shared/terraform.tfvars - git commit -m "Add App Infra directional rules." +1. Commit and push the changes. + + ```bash + git add . + git commit -m "Add infra pipeline directional policies" git push - cd ../ + + cd .. ``` 1. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. @@ -414,7 +458,7 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' git commit -m "Initial nonproduction commit." ``` -1. Checkout shared `production`. Run `init` and `plan` and review output for environment development. +1. Checkout shared `production`. Run `init` and `plan` and review output for production development. ```bash git checkout production @@ -446,32 +490,100 @@ If you received any errors or made any changes to the Terraform config or any `. unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -1. Use `terraform output` to get the APP Infra Pipeline cloud build project number. +1. Before move to the next step, configure directional policies for your perimeter. + +1. Use `terraform output` to get the Seed project ID and the organization step Terraform service account from gcp-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash - export cloudbuild_project_number=$(terraform -chdir="gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_number) - echo $cloudbuild_project_number - sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" gcp-org/envs/shared/service_control.tf + export SEED_PROJECT_ID=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw seed_project_id) + echo ${SEED_PROJECT_ID} + + export GOOGLE_IMPERSONATE_SERVICE_ACCOUNT=$(terraform -chdir="../gcp-bootstrap/envs/shared/" output -raw organization_step_terraform_service_account_email) + echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -2. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` variable to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` variable to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file, run `plan` and `apply`. +1. Use `terraform output` to get the APP Infra Pipeline cloud build project id and project number. ```bash - cd gcp-org - git checkout production + cd ../gcp-org + + export cloudbuild_project_number=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_number) + echo "cloud build project number = $cloudbuild_project_number" + export cloudbuild_project_id=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_id) + echo "cloud build project id = $cloudbuild_project_id" + sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" /envs/shared/service_control.tf + sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" /envs/shared/service_control.tf + ``` + +1. Use `terraform output` to get the Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project. +1. Use `gsutil cat` to get the project numbers of the SVPC and Peering projects in each environment (production, nonproduction, and development) for configuring the directional app infra policies. + + ```bash + export projects_gcs_bucket_tfstate=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw projects_gcs_bucket_tfstate) + echo "projects_gcs_bucket_tfstate = ${projects_gcs_bucket_tfstate}" + + export peering_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_dev = ${peering_project_number_dev}" + sed -i'' -e "s/PRJS_DEV_SAMPLE_PEERING_NUMBER/${peering_project_number_dev}/" envs/shared/service_control.tf + + export peering_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_prod = ${peering_project_number_prod}" + sed -i'' -e "s/PRJS_PROD_SAMPLE_PEERING_NUMBER/${peering_project_number_prod}/" envs/shared/service_control.tf + + export peering_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ + | jq -r '.outputs.peering_project_number.value') + echo "peering_project_number_nonprod = ${peering_project_number_nonprod}" + sed -i'' -e "s/PRJS_NONPROD_SAMPLE_PEERING_NUMBER/${peering_project_number_nonprod}/" envs/shared/service_control.tf + + export shared_vpc_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_dev = ${shared_vpc_project_number_dev}" + sed -i'' -e "s/PRJS_DEV_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_dev}/" /envs/shared/service_control.tf + export shared_vpc_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_prod = ${shared_vpc_project_number_prod}" + sed -i'' -e "s/PRJS_PROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_prod}/" /envs/shared/service_control.tf + + export shared_vpc_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ + | jq -r '.outputs.shared_vpc_project_number.value') + echo "shared_vpc_project_number_nonprod = ${shared_vpc_project_number_nonprod}" + sed -i'' -e "s/PRJS_NONPROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_nonprod}/" /envs/shared/service_control.tf + ``` + +1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` and `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. + + ```bash export enforce_vpcsc=$(terraform -chdir="envs/shared/" output -raw enforce_vpcsc); \ echo "enforce_vpcsc" = $enforce_vpcsc if [[ "$enforce_vpcsc" == "false" ]]; then \ + sed -i -E '/^[[:space:]]*\/\/required_ingress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + else \ + sed -i -E '/^[[:space:]]*\/\/required_ingress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ + fi + if [[ "$enforce_vpcsc" == "false" ]]; then \ sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra_dry_run[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ else \ sed -i -E '/^[[:space:]]*\/\/required_egress_rules_app_infra[[:space:]]*=/ s|^[[:space:]]*//||' envs/shared/terraform.tfvars; \ fi + ``` - ./tf-wrapper.sh plan production - ./tf-wrapper.sh apply production +1. Run `plan` and `apply` and output for production development. Commit and save the changes. - git add envs/shared/terraform.tfvars - git commit -m "Add App Infra egress rule." - cd ../ + ```bash + ./tf-wrapper plan production + ./tf-wrapper apply production + git commit -m "Add infra pipeline directional policies" + + cd .. ``` + +1. Unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. + + ```bash + unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT + ``` + +1. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. From 1fa041f8422715b190de61a31bfc6f75850e5f5e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 18 Aug 2025 16:18:19 -0300 Subject: [PATCH 075/114] fix egress policies keys --- 1-org/envs/shared/service_control.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 5dc051f31..a83b47430 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -823,7 +823,7 @@ module "service_control" { ingress_policies_keys_dry_run = local.ingress_policies_keys_dry_run egress_policies_keys_dry_run = local.egress_policies_keys_dry_run ingress_policies_keys = local.ingress_policies_keys - egress_policies_keys = local.egress_policies_keys_dry_run + egress_policies_keys = local.egress_policies_keys ingress_policies = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, local.required_ingress_rules_app_infra, var.ingress_policies)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) ingress_policies_dry_run = var.required_ingress_rules_app_infra_dry_run ? distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules_dry_run, local.required_ingress_rules_app_infra_dry_run, var.ingress_policies_dry_run)) : distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run)) egress_policies = var.required_egress_rules_app_infra ? distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules, local.required_egress_rules_app_infra)) : distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) From c68d62bd983145c521fccdc7a14870326dfe52cc Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 21 Aug 2025 11:39:50 -0300 Subject: [PATCH 076/114] fix scc ingress rule and keys --- 1-org/envs/shared/service_control.tf | 227 +++++++++++++++++++++++++-- 1 file changed, 216 insertions(+), 11 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index a83b47430..a5179e2ea 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -207,10 +207,12 @@ locals { [for p in local.projects : "${p}"] ) - ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) - egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) - ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) - egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) + enable_scc_resources_in_terraform_dry_run = var.enable_scc_resources_in_terraform ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) + enable_scc_resources_in_terraform = var.enable_scc_resources_in_terraform ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) + ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], local.enable_scc_resources_in_terraform_dry_run) : local.enable_scc_resources_in_terraform + egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) + ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], local.enable_scc_resources_in_terraform) : local.enable_scc_resources_in_terraform + egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) ingress_policies_map_dry_run = var.required_ingress_rules_app_infra_dry_run ? zipmap( local.ingress_policies_keys_dry_run, @@ -308,7 +310,7 @@ locals { }, ] - required_ingress_rules_dry_run = [ + required_ingress_rules_dry_run = var.enable_scc_resources_in_terraform ? [ { from = { identities = [ @@ -363,6 +365,28 @@ locals { } } }, + { + from = { + identities = [ + "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, { from = { identities = [ @@ -410,10 +434,11 @@ locals { } } }, + ] : [ { from = { identities = [ - "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", + "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", ] sources = { access_levels = [ @@ -423,12 +448,91 @@ locals { } to = { resources = [ - "projects/${module.scc_notifications.project_number}" + "projects/${module.org_billing_export.project_number}" ] operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", + "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.org_audit_logs.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + + "pubsub.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { methods = ["*"] } + + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "iam.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "cloudbuild.googleapis.com" = { + methods = ["*"] + } } } }, @@ -517,7 +621,7 @@ locals { }, ] - required_ingress_rules = [ + required_ingress_rules = var.enable_scc_resources_in_terraform ? [ { from = { identities = [ @@ -564,6 +668,30 @@ locals { "pubsub.googleapis.com" = { methods = ["*"] } + + "storage.googleapis.com" = { + methods = ["*"] + } + + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { "storage.googleapis.com" = { methods = ["*"] } @@ -617,10 +745,11 @@ locals { } } }, + ] : [ { from = { identities = [ - "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", + "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", ] sources = { access_levels = [ @@ -630,15 +759,92 @@ locals { } to = { resources = [ - "projects/${module.scc_notifications.project_number}" + "projects/${module.org_billing_export.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", + "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", + ] + sources = { + access_levels = [ + "*" + ] + } + } + to = { + resources = [ + "projects/${module.org_audit_logs.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + + "pubsub.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + { + from = { + identities = [ + "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" ] operations = { + "iam.googleapis.com" = { + methods = ["*"] + } "storage.googleapis.com" = { methods = ["*"] } } } }, + { + from = { + identities = [ + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + ] + sources = { + resources = [ + "projects/${local.cloudbuild_project_number}" + ] + } + } + to = { + resources = [ + "projects/${local.seed_project_number}" + ] + operations = { + "cloudbuild.googleapis.com" = { + methods = ["*"] + } + } + } + }, ] required_ingress_rules_app_infra = [ @@ -797,7 +1003,6 @@ locals { ] } - module "service_control" { source = "../../modules/service_control" From 8df3dc7805c3dbd5cdb7f9dc2ac44a6b6380e36b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 21 Aug 2025 11:52:55 -0300 Subject: [PATCH 077/114] fix helper --- helpers/foundation-deployer/stages/apply.go | 16 +++++----------- helpers/foundation-deployer/stages/data.go | 13 +++++-------- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/helpers/foundation-deployer/stages/apply.go b/helpers/foundation-deployer/stages/apply.go index 174acb4a5..8329c451d 100644 --- a/helpers/foundation-deployer/stages/apply.go +++ b/helpers/foundation-deployer/stages/apply.go @@ -195,8 +195,11 @@ func DeployBootstrapStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, c Co func DeployOrgStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, outputs BootstrapOutputs, c CommonConf) error { createACMAPolicy := testutils.GetOrgACMPolicyID(t, tfvars.OrgID) == "" + AccessContextManagerPolicyID := testutils.GetOrgACMPolicyID(t, tfvars.OrgID) orgTfvars := OrgTfvars{ + AccessContextManagerPolicyID: AccessContextManagerPolicyID, + PerimeterAdditionalMembers: tfvars.PerimeterAdditionalMembers, DomainsToAllow: tfvars.DomainsToAllow, EssentialContactsDomains: tfvars.EssentialContactsDomains, SccNotificationName: tfvars.SccNotificationName, @@ -305,9 +308,8 @@ func DeployNetworksStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, outpu } // common commonTfvars := NetCommonTfvars{ - Domain: tfvars.Domain, - PerimeterAdditionalMembers: tfvars.PerimeterAdditionalMembers, - RemoteStateBucket: outputs.RemoteStateBucket, + Domain: tfvars.Domain, + RemoteStateBucket: outputs.RemoteStateBucket, } if tfvars.EnableHubAndSpoke { commonTfvars.EnableHubAndSpokeTransitivity = &tfvars.EnableHubAndSpokeTransitivity @@ -316,14 +318,6 @@ func DeployNetworksStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, outpu if err != nil { return err } - //access_context - accessContextTfvars := NetAccessContextTfvars{ - AccessContextManagerPolicyID: testutils.GetOrgACMPolicyID(t, tfvars.OrgID), - } - err = utils.WriteTfvars(filepath.Join(c.FoundationPath, step, "access_context.auto.tfvars"), accessContextTfvars) - if err != nil { - return err - } conf := utils.CloneCSR(t, NetworksRepo, filepath.Join(c.CheckoutPath, NetworksRepo), outputs.CICDProject, c.Logger) stageConf := StageConf{ diff --git a/helpers/foundation-deployer/stages/data.go b/helpers/foundation-deployer/stages/data.go index 86c569a8b..83a89f677 100644 --- a/helpers/foundation-deployer/stages/data.go +++ b/helpers/foundation-deployer/stages/data.go @@ -215,6 +215,8 @@ type BootstrapTfvars struct { } type OrgTfvars struct { + AccessContextManagerPolicyID string `hcl:"access_context_manager_policy_id"` + PerimeterAdditionalMembers []string `hcl:"perimeter_additional_members"` DomainsToAllow []string `hcl:"domains_to_allow"` EssentialContactsDomains []string `hcl:"essential_contacts_domains_to_allow"` SccNotificationName string `hcl:"scc_notification_name"` @@ -238,10 +240,9 @@ type EnvsTfvars struct { } type NetCommonTfvars struct { - Domain string `hcl:"domain"` - PerimeterAdditionalMembers []string `hcl:"perimeter_additional_members"` - RemoteStateBucket string `hcl:"remote_state_bucket"` - EnableHubAndSpokeTransitivity *bool `hcl:"enable_hub_and_spoke_transitivity"` + Domain string `hcl:"domain"` + RemoteStateBucket string `hcl:"remote_state_bucket"` + EnableHubAndSpokeTransitivity *bool `hcl:"enable_hub_and_spoke_transitivity"` } type NetSharedTfvars struct { @@ -252,10 +253,6 @@ type NetProductionTfvars struct { TargetNameServerAddresses []ServerAddress `hcl:"target_name_server_addresses"` } -type NetAccessContextTfvars struct { - AccessContextManagerPolicyID string `hcl:"access_context_manager_policy_id"` -} - type ProjCommonTfvars struct { RemoteStateBucket string `hcl:"remote_state_bucket"` } From 917ee6c532a6b9e46ecd111b1caf1b4935220de1 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 22 Aug 2025 13:59:08 -0300 Subject: [PATCH 078/114] fix network hub and README hub and spoke --- 1-org/envs/shared/service_control.tf | 8 +++++++- 3-networks-hub-and-spoke/README.md | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index a5179e2ea..6d950556a 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -165,7 +165,7 @@ locals { module.common_kms.project_number, module.org_secrets.project_number, module.interconnect.project_number, - module.network_hub.project_number, + module.network_hub[0].project_number, module.scc_notifications.project_number, ], local.shared_vpc_projects_numbers)) : (concat([ local.seed_project_number, @@ -240,6 +240,7 @@ locals { required_egress_rules_dry_run = [ { + title = "ER seed -> cicd" from = { identities = [ "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", @@ -262,6 +263,7 @@ locals { } }, { + title = "ER seed -> scc" from = { identities = [ "serviceAccount:${local.organization_service_account}", @@ -287,6 +289,7 @@ locals { required_egress_rules_app_infra_dry_run = [ { + title = "ER app infra -> cicd" from = { identities = [ "serviceAccount:PRJ_APP_INFRA_PIPELINE_NUMBER@cloudbuild.gserviceaccount.com", @@ -312,6 +315,7 @@ locals { required_ingress_rules_dry_run = var.enable_scc_resources_in_terraform ? [ { + title = "IR billing" from = { identities = [ "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", @@ -334,6 +338,7 @@ locals { } }, { + title = "IR sinks" from = { identities = [ "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", @@ -366,6 +371,7 @@ locals { } }, { + title = "IR billing" from = { identities = [ "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", diff --git a/3-networks-hub-and-spoke/README.md b/3-networks-hub-and-spoke/README.md index 7edf310de..3c3e14aa6 100644 --- a/3-networks-hub-and-spoke/README.md +++ b/3-networks-hub-and-spoke/README.md @@ -164,7 +164,6 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get ```bash mv common.auto.example.tfvars common.auto.tfvars mv shared.auto.example.tfvars shared.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. From d779ab79672e2b5ffa9992604611e8d29a7c2a30 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 22 Aug 2025 16:14:52 -0300 Subject: [PATCH 079/114] add directional policies title --- 1-org/envs/shared/service_control.tf | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 6d950556a..fe66fbda8 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -371,7 +371,7 @@ locals { } }, { - title = "IR billing" + title = "IR scc" from = { identities = [ "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", @@ -394,6 +394,7 @@ locals { } }, { + title = "IR service cicd -> seed" from = { identities = [ "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", @@ -419,6 +420,7 @@ locals { } }, { + title = "IR cicd -> seed" from = { identities = [ "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", @@ -442,6 +444,7 @@ locals { }, ] : [ { + title = "IR billing" from = { identities = [ "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", @@ -464,6 +467,7 @@ locals { } }, { + title = "IR sinks" from = { identities = [ "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", @@ -496,6 +500,7 @@ locals { } }, { + title = "IR service cicd -> seed" from = { identities = [ "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", @@ -521,6 +526,7 @@ locals { } }, { + title = "IR cicd -> seed" from = { identities = [ "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", @@ -546,6 +552,7 @@ locals { required_ingress_rules_app_infra_dry_run = [ { + title = "IR cicd -> app infra" from = { identities = [ "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", @@ -574,6 +581,7 @@ locals { } }, { + title = "IR app infra -> seed" from = { identities = [ "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", @@ -596,6 +604,7 @@ locals { } }, { + title = "IR app infra -> prjs" from = { identities = [ "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", @@ -629,6 +638,7 @@ locals { required_ingress_rules = var.enable_scc_resources_in_terraform ? [ { + title = "IR billing" from = { identities = [ "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", @@ -651,6 +661,7 @@ locals { } }, { + title = "IR sinks" from = { identities = [ "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", @@ -683,6 +694,7 @@ locals { } }, { + title = "IR scc" from = { identities = [ "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", @@ -705,6 +717,7 @@ locals { } }, { + title = "IR service cicd -> seed" from = { identities = [ "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", @@ -730,6 +743,7 @@ locals { } }, { + title = "IR cicd -> seed" from = { identities = [ "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", @@ -753,6 +767,7 @@ locals { }, ] : [ { + title = "IR billing" from = { identities = [ "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", @@ -775,6 +790,7 @@ locals { } }, { + title = "IR sinks" from = { identities = [ "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", @@ -798,13 +814,16 @@ locals { "pubsub.googleapis.com" = { methods = ["*"] } + "storage.googleapis.com" = { methods = ["*"] } + } } }, { + title = "IR service cicd -> seed" from = { identities = [ "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", @@ -830,6 +849,7 @@ locals { } }, { + title = "IR cicd -> seed" from = { identities = [ "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", @@ -855,6 +875,7 @@ locals { required_ingress_rules_app_infra = [ { + title = "IR cicd -> app infra" from = { identities = [ "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", @@ -883,6 +904,7 @@ locals { } }, { + title = "IR app infra -> seed" from = { identities = [ "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", @@ -905,6 +927,7 @@ locals { } }, { + title = "IR app infra -> prjs" from = { identities = [ "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", @@ -985,6 +1008,7 @@ locals { required_egress_rules_app_infra = [ { + title = "ER app infra -> cicd" from = { identities = [ "serviceAccount:PRJ_APP_INFRA_PIPELINE_NUMBER@cloudbuild.gserviceaccount.com", From abb342b27bed5e7b3a8b04d3526fbce9228c2749 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 26 Aug 2025 14:19:26 -0300 Subject: [PATCH 080/114] fix bash commands --- 4-projects/README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/4-projects/README.md b/4-projects/README.md index 57854218b..a0ad86cd9 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -228,14 +228,15 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' 1. Before move to the next step, configure directional policies for your perimeter. +1. Navigate to `gcp-org`. 1. Use `terraform output` to get the APP Infra Pipeline cloud build project id and project number. ```bash - cd ../gcp-org + cd ../gcp-org/ - export cloudbuild_project_number=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_number) + export cloudbuild_project_number=$(terraform -chdir="../gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_number) echo "cloud build project number = $cloudbuild_project_number" - export cloudbuild_project_id=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_id) + export cloudbuild_project_id=$(terraform -chdir="../gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_id) echo "cloud build project id = $cloudbuild_project_id" sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" /envs/shared/service_control.tf sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" /envs/shared/service_control.tf @@ -502,14 +503,17 @@ If you received any errors or made any changes to the Terraform config or any `. echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` +1. Before move to the next step, configure directional policies for your perimeter. + +1. Navigate to `gcp-org`. 1. Use `terraform output` to get the APP Infra Pipeline cloud build project id and project number. ```bash - cd ../gcp-org + cd ../gcp-org/ - export cloudbuild_project_number=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_number) + export cloudbuild_project_number=$(terraform -chdir="../gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_number) echo "cloud build project number = $cloudbuild_project_number" - export cloudbuild_project_id=$(terraform -chdir="business_unit_1/shared/" output -raw cloudbuild_project_id) + export cloudbuild_project_id=$(terraform -chdir="../gcp-projects/business_unit_1/shared/" output -raw cloudbuild_project_id) echo "cloud build project id = $cloudbuild_project_id" sed -i'' -e "s/PRJ_APP_INFRA_PIPELINE_NUMBER/${cloudbuild_project_number}/" /envs/shared/service_control.tf sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" /envs/shared/service_control.tf From 9855e0e61b607bb7e1c0269ca692ff24cbfa413c Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 28 Aug 2025 18:47:46 -0300 Subject: [PATCH 081/114] rm scc --- 1-org/envs/shared/service_control.tf | 279 ++------------------------- 1 file changed, 12 insertions(+), 267 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index fe66fbda8..edd2b53cd 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -207,12 +207,15 @@ locals { [for p in local.projects : "${p}"] ) - enable_scc_resources_in_terraform_dry_run = var.enable_scc_resources_in_terraform ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) - enable_scc_resources_in_terraform = var.enable_scc_resources_in_terraform ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "service_scc_to_scc"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) - ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], local.enable_scc_resources_in_terraform_dry_run) : local.enable_scc_resources_in_terraform - egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) - ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], local.enable_scc_resources_in_terraform) : local.enable_scc_resources_in_terraform - egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) + projects_map_dry_run = zipmap( + local.project_keys, + [for p in local.projects : "${p}"] + ) + + ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env", "billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) + egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) + ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env", "billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) + egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) ingress_policies_map_dry_run = var.required_ingress_rules_app_infra_dry_run ? zipmap( local.ingress_policies_keys_dry_run, @@ -313,136 +316,7 @@ locals { }, ] - required_ingress_rules_dry_run = var.enable_scc_resources_in_terraform ? [ - { - title = "IR billing" - from = { - identities = [ - "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", - ] - sources = { - access_levels = [ - "*" - ] - } - } - to = { - resources = [ - "projects/${module.org_billing_export.project_number}" - ] - operations = { - "logging.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - title = "IR sinks" - from = { - identities = [ - "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", - "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", - ] - sources = { - access_levels = [ - "*" - ] - } - } - to = { - resources = [ - "projects/${module.org_audit_logs.project_number}" - ] - operations = { - "logging.googleapis.com" = { - methods = ["*"] - } - - "pubsub.googleapis.com" = { - methods = ["*"] - } - - "storage.googleapis.com" = { - methods = ["*"] - } - - } - } - }, - { - title = "IR scc" - from = { - identities = [ - "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", - ] - sources = { - access_levels = [ - "*" - ] - } - } - to = { - resources = [ - "projects/${module.scc_notifications.project_number}" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - title = "IR service cicd -> seed" - from = { - identities = [ - "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.seed_project_number}" - ] - operations = { - "iam.googleapis.com" = { - methods = ["*"] - } - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - title = "IR cicd -> seed" - from = { - identities = [ - "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.seed_project_number}" - ] - operations = { - "cloudbuild.googleapis.com" = { - methods = ["*"] - } - } - } - }, - ] : [ + required_ingress_rules_dry_run = [ { title = "IR billing" from = { @@ -636,136 +510,7 @@ locals { }, ] - required_ingress_rules = var.enable_scc_resources_in_terraform ? [ - { - title = "IR billing" - from = { - identities = [ - "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", - ] - sources = { - access_levels = [ - "*" - ] - } - } - to = { - resources = [ - "projects/${module.org_billing_export.project_number}" - ] - operations = { - "logging.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - title = "IR sinks" - from = { - identities = [ - "serviceAccount:service-${local.parent_id}@gcp-sa-logging.iam.gserviceaccount.com", - "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", - ] - sources = { - access_levels = [ - "*" - ] - } - } - to = { - resources = [ - "projects/${module.org_audit_logs.project_number}" - ] - operations = { - "logging.googleapis.com" = { - methods = ["*"] - } - - "pubsub.googleapis.com" = { - methods = ["*"] - } - - "storage.googleapis.com" = { - methods = ["*"] - } - - } - } - }, - { - title = "IR scc" - from = { - identities = [ - "serviceAccount:service-${module.scc_notifications.project_number}@gcf-admin-robot.iam.gserviceaccount.com", - ] - sources = { - access_levels = [ - "*" - ] - } - } - to = { - resources = [ - "projects/${module.scc_notifications.project_number}" - ] - operations = { - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - title = "IR service cicd -> seed" - from = { - identities = [ - "serviceAccount:service-${local.cloudbuild_project_number}@gcp-sa-cloudbuild.iam.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.seed_project_number}" - ] - operations = { - "iam.googleapis.com" = { - methods = ["*"] - } - "storage.googleapis.com" = { - methods = ["*"] - } - } - } - }, - { - title = "IR cicd -> seed" - from = { - identities = [ - "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", - ] - sources = { - resources = [ - "projects/${local.cloudbuild_project_number}" - ] - } - } - to = { - resources = [ - "projects/${local.seed_project_number}" - ] - operations = { - "cloudbuild.googleapis.com" = { - methods = ["*"] - } - } - } - }, - ] : [ + required_ingress_rules = [ { title = "IR billing" from = { @@ -1053,7 +798,7 @@ module "service_control" { "serviceAccount:${local.organization_service_account}", "serviceAccount:${local.environment_service_account}", ], var.perimeter_additional_members)) - resources_dry_run = concat(values(local.projects_map), var.resources_dry_run) + resources_dry_run = concat(values(local.projects_map_dry_run), var.resources_dry_run) resource_keys_dry_run = local.project_keys ingress_policies_keys_dry_run = local.ingress_policies_keys_dry_run egress_policies_keys_dry_run = local.egress_policies_keys_dry_run From 21540a66f0be0b1d0be9d2a99f6b7d4007a16df9 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 28 Aug 2025 18:48:10 -0300 Subject: [PATCH 082/114] add outputs --- 2-environments/envs/production/README.md | 1 + 2-environments/envs/production/outputs.tf | 5 +++++ 2-environments/modules/env_baseline/README.md | 1 + 2-environments/modules/env_baseline/outputs.tf | 5 +++++ 4-projects/business_unit_1/development/README.md | 1 + 4-projects/business_unit_1/development/outputs.tf | 5 +++++ 4-projects/modules/base_env/outputs.tf | 5 +++++ 7 files changed, 23 insertions(+) diff --git a/2-environments/envs/production/README.md b/2-environments/envs/production/README.md index 629d228db..f6f936b8f 100644 --- a/2-environments/envs/production/README.md +++ b/2-environments/envs/production/README.md @@ -18,6 +18,7 @@ | env\_kms\_project\_id | Project for environment Cloud Key Management Service (KMS). | | env\_kms\_project\_number | Project Number for environment Cloud Key Management Service (KMS). | | env\_secrets\_project\_id | Project for environment related secrets. | +| env\_secrets\_project\_number | Project for environment related secrets. | diff --git a/2-environments/envs/production/outputs.tf b/2-environments/envs/production/outputs.tf index 0d60ebe5f..4aaae7585 100644 --- a/2-environments/envs/production/outputs.tf +++ b/2-environments/envs/production/outputs.tf @@ -24,6 +24,11 @@ output "env_secrets_project_id" { value = module.env.env_secrets_project_id } +output "env_secrets_project_number" { + description = "Project for environment related secrets." + value = module.env.env_secrets_project_number +} + output "env_kms_project_id" { description = "Project for environment Cloud Key Management Service (KMS)." value = module.env.env_kms_project_id diff --git a/2-environments/modules/env_baseline/README.md b/2-environments/modules/env_baseline/README.md index 8d9f8ecf1..a0d9b0820 100644 --- a/2-environments/modules/env_baseline/README.md +++ b/2-environments/modules/env_baseline/README.md @@ -22,5 +22,6 @@ | env\_kms\_project\_id | Project for environment Cloud Key Management Service (KMS). | | env\_kms\_project\_number | Project number for envinronment Cloud Key Management Service (KMS). | | env\_secrets\_project\_id | Project for environment secrets. | +| env\_secrets\_project\_number | Project number for environment secrets. | diff --git a/2-environments/modules/env_baseline/outputs.tf b/2-environments/modules/env_baseline/outputs.tf index b949becb9..d7ebff590 100644 --- a/2-environments/modules/env_baseline/outputs.tf +++ b/2-environments/modules/env_baseline/outputs.tf @@ -24,6 +24,11 @@ output "env_secrets_project_id" { value = module.env_secrets.project_id } +output "env_secrets_project_number" { + description = "Project number for environment secrets." + value = module.env_secrets.project_number +} + output "env_kms_project_id" { description = "Project for environment Cloud Key Management Service (KMS)." value = module.env_kms.project_id diff --git a/4-projects/business_unit_1/development/README.md b/4-projects/business_unit_1/development/README.md index cec9febcb..bf6849859 100644 --- a/4-projects/business_unit_1/development/README.md +++ b/4-projects/business_unit_1/development/README.md @@ -21,6 +21,7 @@ | bucket | The created storage bucket. | | default\_region | The default region for the project. | | floating\_project | Project sample floating project. | +| floating\_project\_number | Project number sample floating project. | | iap\_firewall\_tags | The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project. | | keyring | The name of the keyring. | | keys | List of created key names. | diff --git a/4-projects/business_unit_1/development/outputs.tf b/4-projects/business_unit_1/development/outputs.tf index 4be621231..5fb91857b 100644 --- a/4-projects/business_unit_1/development/outputs.tf +++ b/4-projects/business_unit_1/development/outputs.tf @@ -19,6 +19,11 @@ output "floating_project" { value = module.env.floating_project } +output "floating_project_number" { + description = "Project number sample floating project." + value = module.env.floating_project_number +} + output "peering_project" { description = "Project sample peering project id." value = module.env.peering_project diff --git a/4-projects/modules/base_env/outputs.tf b/4-projects/modules/base_env/outputs.tf index 4844cdf83..a0e33cc12 100644 --- a/4-projects/modules/base_env/outputs.tf +++ b/4-projects/modules/base_env/outputs.tf @@ -19,6 +19,11 @@ output "floating_project" { value = module.floating_project.project_id } +output "floating_project" { + description = "Project sample floating project." + value = module.floating_project.project_number +} + output "peering_project" { description = "Project sample peering project id." value = module.peering_project.project_id From 7c19dee1f3a4c34921dd8414fbaee9c6d472993e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 28 Aug 2025 18:48:50 -0300 Subject: [PATCH 083/114] updt integration tests --- test/integration/envs/envs_test.go | 18 ++ test/integration/networks/networks_test.go | 191 +-------------- test/integration/org/org_test.go | 229 +++++++++++++++++- .../projects-shared/projects_shared_test.go | 16 ++ test/integration/projects/projects_test.go | 28 ++- 5 files changed, 269 insertions(+), 213 deletions(-) diff --git a/test/integration/envs/envs_test.go b/test/integration/envs/envs_test.go index 15de28f31..be3e4e9bf 100644 --- a/test/integration/envs/envs_test.go +++ b/test/integration/envs/envs_test.go @@ -16,12 +16,14 @@ package envs import ( "fmt" + "strings" "testing" "time" "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/utils" + "github.com/gruntwork-io/terratest/modules/terraform" "github.com/stretchr/testify/assert" "github.com/terraform-google-modules/terraform-example-foundation/test/integration/testutils" @@ -65,6 +67,17 @@ func TestEnvs(t *testing.T) { tft.WithVars(vars), tft.WithBackendConfig(backendConfig), ) + + orgState := tft.NewTFBlueprintTest(t, + tft.WithTFDir("../../../1-org/envs/shared"), + tft.WithVars(vars), + tft.WithBackendConfig(backendConfig), + ) + + perimeterName := terraform.Output(t, orgState.GetTFOptions(), "service_perimeter_name") + orgID := bootstrap.GetTFSetupStringOutput("org_id") + policyID := testutils.GetOrgACMPolicyID(t, orgID) + envs.DefineVerify( func(assert *assert.Assertions) { // perform default verification ensuring Terraform reports no additional changes on an applied blueprint @@ -109,10 +122,15 @@ func TestEnvs(t *testing.T) { }, } { projectID := envs.GetStringOutput(projectEnvOutput.projectOutput) + projectNumber := envs.GetStringOutput(strings.ReplaceAll(projectEnvOutput.projectOutput, "_id", "_number")) prj := gcloud.Runf(t, "projects describe %s", projectID) assert.Equal(projectID, prj.Get("projectId").String(), fmt.Sprintf("project %s should exist", projectID)) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) + perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", perimeterName, policyID)) + assert.NoError(err) + assert.True(strings.Contains(perimeter, projectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s (number)", perimeterName, projectNumber)) + enabledAPIS := gcloud.Runf(t, "services list --project %s", projectID).Array() listApis := testutils.GetResultFieldStrSlice(enabledAPIS, "config.name") assert.Subset(listApis, projectEnvOutput.apis, "APIs should have been enabled") diff --git a/test/integration/networks/networks_test.go b/test/integration/networks/networks_test.go index 48b401c91..2bf38aa67 100644 --- a/test/integration/networks/networks_test.go +++ b/test/integration/networks/networks_test.go @@ -24,9 +24,7 @@ import ( "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/gcloud" "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/utils" - "github.com/gruntwork-io/terratest/modules/terraform" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/terraform-google-modules/terraform-example-foundation/test/integration/testutils" ) @@ -75,11 +73,8 @@ func TestNetworks(t *testing.T) { tft.WithTFDir("../../../0-bootstrap"), ) - orgID := terraform.OutputMap(t, bootstrap.GetTFOptions(), "common_config")["org_id"] networkMode := getNetworkMode(t) firewallMode := getFirewallMode(t) - policyID := testutils.GetOrgACMPolicyID(t, orgID) - require.NotEmpty(t, policyID, "Access Context Manager Policy ID must be configured in the organization for the test to proceed.") // Configure impersonation for test execution terraformSA := bootstrap.GetStringOutput("networks_step_terraform_service_account_email") @@ -90,131 +85,6 @@ func TestNetworks(t *testing.T) { "bucket": backend_bucket, } - restrictedServices := []string{ - "accessapproval.googleapis.com", - "adsdatahub.googleapis.com", - "aiplatform.googleapis.com", - "alloydb.googleapis.com", - "alpha-documentai.googleapis.com", - "analyticshub.googleapis.com", - "apigee.googleapis.com", - "apigeeconnect.googleapis.com", - "artifactregistry.googleapis.com", - "assuredworkloads.googleapis.com", - "automl.googleapis.com", - "baremetalsolution.googleapis.com", - "batch.googleapis.com", - "bigquery.googleapis.com", - "bigquerydatapolicy.googleapis.com", - "bigquerydatatransfer.googleapis.com", - "bigquerymigration.googleapis.com", - "bigqueryreservation.googleapis.com", - "bigtable.googleapis.com", - "binaryauthorization.googleapis.com", - "cloud.googleapis.com", - "cloudasset.googleapis.com", - "cloudbuild.googleapis.com", - "clouddebugger.googleapis.com", - "clouddeploy.googleapis.com", - "clouderrorreporting.googleapis.com", - "cloudfunctions.googleapis.com", - "cloudkms.googleapis.com", - "cloudprofiler.googleapis.com", - "cloudresourcemanager.googleapis.com", - "cloudscheduler.googleapis.com", - "cloudsearch.googleapis.com", - "cloudtrace.googleapis.com", - "composer.googleapis.com", - "compute.googleapis.com", - "connectgateway.googleapis.com", - "contactcenterinsights.googleapis.com", - "container.googleapis.com", - "containeranalysis.googleapis.com", - "containerfilesystem.googleapis.com", - "containerregistry.googleapis.com", - "containerthreatdetection.googleapis.com", - "datacatalog.googleapis.com", - "dataflow.googleapis.com", - "datafusion.googleapis.com", - "datamigration.googleapis.com", - "dataplex.googleapis.com", - "dataproc.googleapis.com", - "datastream.googleapis.com", - "dialogflow.googleapis.com", - "dlp.googleapis.com", - "dns.googleapis.com", - "documentai.googleapis.com", - "domains.googleapis.com", - "eventarc.googleapis.com", - "file.googleapis.com", - "firebaseappcheck.googleapis.com", - "firebaserules.googleapis.com", - "firestore.googleapis.com", - "gameservices.googleapis.com", - "gkebackup.googleapis.com", - "gkeconnect.googleapis.com", - "gkehub.googleapis.com", - "healthcare.googleapis.com", - "iam.googleapis.com", - "iamcredentials.googleapis.com", - "iaptunnel.googleapis.com", - "ids.googleapis.com", - "integrations.googleapis.com", - "kmsinventory.googleapis.com", - "krmapihosting.googleapis.com", - "language.googleapis.com", - "lifesciences.googleapis.com", - "logging.googleapis.com", - "managedidentities.googleapis.com", - "memcache.googleapis.com", - "meshca.googleapis.com", - "meshconfig.googleapis.com", - "metastore.googleapis.com", - "ml.googleapis.com", - "monitoring.googleapis.com", - "networkconnectivity.googleapis.com", - "networkmanagement.googleapis.com", - "networksecurity.googleapis.com", - "networkservices.googleapis.com", - "notebooks.googleapis.com", - "opsconfigmonitoring.googleapis.com", - "orgpolicy.googleapis.com", - "osconfig.googleapis.com", - "oslogin.googleapis.com", - "privateca.googleapis.com", - "pubsub.googleapis.com", - "pubsublite.googleapis.com", - "recaptchaenterprise.googleapis.com", - "recommender.googleapis.com", - "redis.googleapis.com", - "retail.googleapis.com", - "run.googleapis.com", - "secretmanager.googleapis.com", - "servicecontrol.googleapis.com", - "servicedirectory.googleapis.com", - "spanner.googleapis.com", - "speakerid.googleapis.com", - "speech.googleapis.com", - "sqladmin.googleapis.com", - "storage.googleapis.com", - "storagetransfer.googleapis.com", - "sts.googleapis.com", - "texttospeech.googleapis.com", - "timeseriesinsights.googleapis.com", - "tpu.googleapis.com", - "trafficdirector.googleapis.com", - "transcoder.googleapis.com", - "translate.googleapis.com", - "videointelligence.googleapis.com", - "vision.googleapis.com", - "visionai.googleapis.com", - "vmmigration.googleapis.com", - "vpcaccess.googleapis.com", - "webrisk.googleapis.com", - "workflows.googleapis.com", - "workstations.googleapis.com", - } - cidrRanges := map[string][]string{ "development": []string{"10.8.64.0/18", "10.9.64.0/18"}, "nonproduction": []string{"10.8.128.0/18", "10.9.128.0/18"}, @@ -227,50 +97,6 @@ func TestNetworks(t *testing.T) { "production": "10.17.0.8", } - ingressPolicies := []map[string]interface{}{ - { - "from": map[string]interface{}{ - "sources": map[string][]string{ - "access_levels": {"*"}, - }, - "identity_type": "ANY_IDENTITY", - }, - "to": map[string]interface{}{ - "resources": []string{"*"}, - "operations": map[string]map[string][]string{ - "storage.googleapis.com": { - "methods": { - "google.storage.objects.get", - "google.storage.objects.list", - }, - }, - }, - }, - }, - } - - egressPolicies := []map[string]interface{}{ - { - "from": map[string]interface{}{ - "sources": map[string][]string{ - "access_levels": {"*"}, - }, - "identity_type": "ANY_IDENTITY", - }, - "to": map[string]interface{}{ - "resources": []string{"*"}, - "operations": map[string]map[string][]string{ - "storage.googleapis.com": { - "methods": { - "google.storage.objects.get", - "google.storage.objects.list", - }, - }, - }, - }, - }, - } - envStage := os.Getenv(utils.RUN_STAGE_ENV_VAR) var envNames []string @@ -293,11 +119,7 @@ func TestNetworks(t *testing.T) { t.Run(envName, func(t *testing.T) { vars := map[string]interface{}{ - "access_context_manager_policy_id": policyID, - "remote_state_bucket": backend_bucket, - "ingress_policies": ingressPolicies, - "egress_policies": egressPolicies, - "perimeter_additional_members": []string{}, + "remote_state_bucket": backend_bucket, } var tfdDir string @@ -327,19 +149,8 @@ func TestNetworks(t *testing.T) { // Resource issue: https://github.com/hashicorp/terraform-provider-google/issues/16804 // networks.DefaultVerify(assert) - servicePerimeterLink := fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", policyID, networks.GetStringOutput("service_perimeter_name")) - accessLevel := fmt.Sprintf("accessPolicies/%s/accessLevels/%s", policyID, networks.GetStringOutput("access_level_name_dry_run")) networkNames := getNetworkResourceNames(envCode, networkMode, firewallMode) - servicePerimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", servicePerimeterLink, policyID)) - assert.NoError(err) - perimeterName := networks.GetStringOutput("service_perimeter_name") - assert.True(strings.Contains(servicePerimeter, perimeterName), fmt.Sprintf("service perimeter %s should exist", perimeterName)) - assert.True(strings.Contains(servicePerimeter, accessLevel), fmt.Sprintf("service perimeter %s should have access level %s", servicePerimeterLink, accessLevel)) - for _, service := range restrictedServices { - assert.True(strings.Contains(servicePerimeter, service), fmt.Sprintf("service perimeter %s should restrict all supported services", servicePerimeterLink)) - } - projectID := networks.GetStringOutput("shared_vpc_host_project_id") if strings.Contains(projectID, "-p-") && networkMode != "-spoke" { diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go index 31a913f64..03ea08d55 100644 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -17,6 +17,7 @@ package org import ( "fmt" "strconv" + "strings" "testing" "time" @@ -38,20 +39,51 @@ func TestOrg(t *testing.T) { backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") - vars := map[string]interface{}{ - "remote_state_bucket": backend_bucket, - "log_export_storage_force_destroy": "true", - "folder_deletion_protection": false, - "project_deletion_policy": "DELETE", + ingressPolicies := []map[string]interface{}{ + { + "from": map[string]interface{}{ + "sources": map[string][]string{ + "access_levels": {"*"}, + }, + "identity_type": "ANY_IDENTITY", + }, + "to": map[string]interface{}{ + "resources": []string{"*"}, + "operations": map[string]map[string][]string{ + "storage.googleapis.com": { + "methods": { + "google.storage.objects.get", + "google.storage.objects.list", + }, + }, + }, + }, + }, } - backendConfig := map[string]interface{}{ - "bucket": backend_bucket, + egressPolicies := []map[string]interface{}{ + { + "from": map[string]interface{}{ + "sources": map[string][]string{ + "access_levels": {"*"}, + }, + "identity_type": "ANY_IDENTITY", + }, + "to": map[string]interface{}{ + "resources": []string{"*"}, + "operations": map[string]map[string][]string{ + "storage.googleapis.com": { + "methods": { + "google.storage.objects.get", + "google.storage.objects.list", + }, + }, + }, + }, + }, } - // Configure impersonation for test execution terraformSA := bootstrap.GetStringOutput("organization_step_terraform_service_account_email") - utils.SetEnv(t, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", terraformSA) // Create Access Context Manager Policy ID if needed orgID := terraform.OutputMap(t, bootstrap.GetTFOptions(), "common_config")["org_id"] @@ -65,6 +97,151 @@ func TestOrg(t *testing.T) { } } + vars := map[string]interface{}{ + "remote_state_bucket": backend_bucket, + "log_export_storage_force_destroy": "true", + "folder_deletion_protection": false, + "project_deletion_policy": "DELETE", + "access_context_manager_policy_id": policyID, + "ingress_policies": ingressPolicies, + "egress_policies": egressPolicies, + "perimeter_additional_members": []string{}, + } + + restrictedServices := []string{ + "serviceusage.googleapis.com", + "essentialcontacts.googleapis.com", + "accessapproval.googleapis.com", + "adsdatahub.googleapis.com", + "aiplatform.googleapis.com", + "alloydb.googleapis.com", + "alpha-documentai.googleapis.com", + "analyticshub.googleapis.com", + "apigee.googleapis.com", + "apigeeconnect.googleapis.com", + "artifactregistry.googleapis.com", + "assuredworkloads.googleapis.com", + "automl.googleapis.com", + "baremetalsolution.googleapis.com", + "batch.googleapis.com", + "bigquery.googleapis.com", + "bigquerydatapolicy.googleapis.com", + "bigquerydatatransfer.googleapis.com", + "bigquerymigration.googleapis.com", + "bigqueryreservation.googleapis.com", + "bigtable.googleapis.com", + "binaryauthorization.googleapis.com", + "cloud.googleapis.com", + "cloudasset.googleapis.com", + "cloudbuild.googleapis.com", + "clouddebugger.googleapis.com", + "clouddeploy.googleapis.com", + "clouderrorreporting.googleapis.com", + "cloudfunctions.googleapis.com", + "cloudkms.googleapis.com", + "cloudprofiler.googleapis.com", + "cloudresourcemanager.googleapis.com", + "cloudscheduler.googleapis.com", + "cloudsearch.googleapis.com", + "cloudtrace.googleapis.com", + "composer.googleapis.com", + "compute.googleapis.com", + "connectgateway.googleapis.com", + "contactcenterinsights.googleapis.com", + "container.googleapis.com", + "containeranalysis.googleapis.com", + "containerfilesystem.googleapis.com", + "containerregistry.googleapis.com", + "containerthreatdetection.googleapis.com", + "datacatalog.googleapis.com", + "dataflow.googleapis.com", + "datafusion.googleapis.com", + "datamigration.googleapis.com", + "dataplex.googleapis.com", + "dataproc.googleapis.com", + "datastream.googleapis.com", + "dialogflow.googleapis.com", + "dlp.googleapis.com", + "dns.googleapis.com", + "documentai.googleapis.com", + "domains.googleapis.com", + "eventarc.googleapis.com", + "file.googleapis.com", + "firebaseappcheck.googleapis.com", + "firebaserules.googleapis.com", + "firestore.googleapis.com", + "gameservices.googleapis.com", + "gkebackup.googleapis.com", + "gkeconnect.googleapis.com", + "gkehub.googleapis.com", + "healthcare.googleapis.com", + "iam.googleapis.com", + "iamcredentials.googleapis.com", + "iaptunnel.googleapis.com", + "ids.googleapis.com", + "integrations.googleapis.com", + "kmsinventory.googleapis.com", + "krmapihosting.googleapis.com", + "language.googleapis.com", + "lifesciences.googleapis.com", + "logging.googleapis.com", + "managedidentities.googleapis.com", + "memcache.googleapis.com", + "meshca.googleapis.com", + "meshconfig.googleapis.com", + "metastore.googleapis.com", + "ml.googleapis.com", + "monitoring.googleapis.com", + "networkconnectivity.googleapis.com", + "networkmanagement.googleapis.com", + "networksecurity.googleapis.com", + "networkservices.googleapis.com", + "notebooks.googleapis.com", + "opsconfigmonitoring.googleapis.com", + "orgpolicy.googleapis.com", + "osconfig.googleapis.com", + "oslogin.googleapis.com", + "privateca.googleapis.com", + "pubsub.googleapis.com", + "pubsublite.googleapis.com", + "recaptchaenterprise.googleapis.com", + "recommender.googleapis.com", + "redis.googleapis.com", + "retail.googleapis.com", + "run.googleapis.com", + "secretmanager.googleapis.com", + "servicecontrol.googleapis.com", + "servicedirectory.googleapis.com", + "spanner.googleapis.com", + "speakerid.googleapis.com", + "speech.googleapis.com", + "sqladmin.googleapis.com", + "storage.googleapis.com", + "storagetransfer.googleapis.com", + "sts.googleapis.com", + "texttospeech.googleapis.com", + "timeseriesinsights.googleapis.com", + "tpu.googleapis.com", + "trafficdirector.googleapis.com", + "transcoder.googleapis.com", + "translate.googleapis.com", + "videointelligence.googleapis.com", + "vision.googleapis.com", + "visionai.googleapis.com", + "vmmigration.googleapis.com", + "vpcaccess.googleapis.com", + "webrisk.googleapis.com", + "workflows.googleapis.com", + "workstations.googleapis.com", + } + + backendConfig := map[string]interface{}{ + "bucket": backend_bucket, + } + + // Configure impersonation for test execution + utils.SetEnv(t, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", terraformSA) + org := tft.NewTFBlueprintTest(t, tft.WithTFDir("../../../1-org/envs/shared"), tft.WithVars(vars), @@ -123,6 +300,16 @@ func TestOrg(t *testing.T) { commonConfig := terraform.OutputMap(t, bootstrap.GetTFOptions(), "common_config") bootstrapFolder := testutils.GetLastSplitElement(commonConfig["bootstrap_folder_name"], "/") + servicePerimeterLink := fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", policyID, org.GetStringOutput("service_perimeter_name")) + accessLevel := fmt.Sprintf("accessPolicies/%s/accessLevels/%s", policyID, org.GetStringOutput("access_level_name_dry_run")) + servicePerimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", servicePerimeterLink, policyID)) + assert.NoError(err) + perimeterName := org.GetStringOutput("service_perimeter_name") + assert.True(strings.Contains(servicePerimeter, perimeterName), fmt.Sprintf("service perimeter %s should exist", perimeterName)) + assert.True(strings.Contains(servicePerimeter, accessLevel), fmt.Sprintf("service perimeter %s should have access level %s", servicePerimeterLink, accessLevel)) + for _, service := range restrictedServices { + assert.True(strings.Contains(servicePerimeter, service), fmt.Sprintf("service perimeter %s should restrict all supported services", servicePerimeterLink)) + } for _, tags := range []struct { folderId string folderName string @@ -377,6 +564,13 @@ func TestOrg(t *testing.T) { assert.Equal(sinkBilling.destination, logSinkBilling.Get("destination").String(), fmt.Sprintf("sink %s should have destination %s", sinkBilling.name, sinkBilling.destination)) } + // verify seed project in perimeter + sharedProjectNumber := bootstrap.GetStringOutput("seed_project_number") + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + projectFormat := fmt.Sprintf("projects/%s", sharedProjectNumber) + perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) + assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) + // hub and spoke infrastructure enable_hub_and_spoke, err := strconv.ParseBool(bootstrap.GetTFSetupStringOutput("enable_hub_and_spoke")) require.NoError(t, err) @@ -389,6 +583,12 @@ func TestOrg(t *testing.T) { projects := gcloud.Run(t, "projects list", gcOps).Array() assert.Equal(1, len(projects), fmt.Sprintf("project %s should exist", projectID)) assert.Equal("ACTIVE", projects[0].Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) + numberOutput := strings.ReplaceAll(hubAndSpokeProjectOutput, "_id", "_number") // "net_hub_project_number" + projectNumber := org.GetStringOutput(numberOutput) + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + projectFormat := fmt.Sprintf("projects/%s", projectNumber) + perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) + assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) } } @@ -445,7 +645,10 @@ func TestOrg(t *testing.T) { projectID := org.GetStringOutput(projectOutput.output) prj := gcloud.Runf(t, "projects describe %s", projectID) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) - + projectNumber := prj.Get("projectNumber").String() + perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", servicePerimeterLink, policyID)) + assert.NoError(err) + assert.True(strings.Contains(perimeter, projectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s (number: %s)", perimeterName, projectID, projectNumber)) enabledAPIS := gcloud.Runf(t, "services list --project %s", projectID).Array() listApis := testutils.GetResultFieldStrSlice(enabledAPIS, "config.name") assert.Subset(listApis, projectOutput.apis, "APIs should have been enabled") @@ -476,10 +679,14 @@ func TestOrg(t *testing.T) { } { envProj := terraform.OutputMapOfObjects(t, org.GetTFOptions(), "shared_vpc_projects")[envName].(map[string]interface{}) projectID := envProj[projectEnvOutput.projectOutput] + projectNumber := fmt.Sprint(envProj["shared_vpc_project_number"]) prj := gcloud.Runf(t, "projects describe %s", projectID) assert.Equal(projectID, prj.Get("projectId").String(), fmt.Sprintf("project %s should exist", projectID)) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) - + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + projectFormat := fmt.Sprintf("projects/%s", projectNumber) + perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) + assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) enabledAPIS := gcloud.Runf(t, "services list --project %s", projectID).Array() listApis := testutils.GetResultFieldStrSlice(enabledAPIS, "config.name") assert.Subset(listApis, projectEnvOutput.apis, "APIs should have been enabled") diff --git a/test/integration/projects-shared/projects_shared_test.go b/test/integration/projects-shared/projects_shared_test.go index 71c14681d..5136a7aa1 100644 --- a/test/integration/projects-shared/projects_shared_test.go +++ b/test/integration/projects-shared/projects_shared_test.go @@ -50,6 +50,16 @@ func TestProjectsShared(t *testing.T) { "cloudkms.googleapis.com", } + orgState := tft.NewTFBlueprintTest(t, + tft.WithTFDir("../../../1-org/envs/shared"), + tft.WithVars(map[string]interface{}{"remote_state_bucket": backend_bucket}), + tft.WithBackendConfig(map[string]interface{}{"bucket": backend_bucket}), + ) + perimeterName := terraform.Output(t, orgState.GetTFOptions(), "service_perimeter_name") + orgID := bootstrap.GetTFSetupStringOutput("org_id") + policyID := testutils.GetOrgACMPolicyID(t, orgID) + servicePerimeterLink := fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", policyID, perimeterName) + for _, tts := range []struct { name string repo string @@ -83,9 +93,15 @@ func TestProjectsShared(t *testing.T) { shared.DefaultVerify(assert) projectID := shared.GetStringOutput("cloudbuild_project_id") + projectNumber := shared.GetStringOutput("cloudbuild_project_number") prj := gcloud.Runf(t, "projects describe %s", projectID) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) + projectFormat := fmt.Sprintf("projects/%s", projectNumber) + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + spec := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) + assert.Contains(spec, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) + enabledAPIS := gcloud.Runf(t, "services list --project %s", projectID).Array() listApis := testutils.GetResultFieldStrSlice(enabledAPIS, "config.name") assert.Subset(listApis, sharedApisEnabled, "APIs should have been enabled") diff --git a/test/integration/projects/projects_test.go b/test/integration/projects/projects_test.go index def083e8d..f155be803 100644 --- a/test/integration/projects/projects_test.go +++ b/test/integration/projects/projects_test.go @@ -71,27 +71,27 @@ func TestProjects(t *testing.T) { } for _, tt := range []struct { - name string - repo string - baseDir string + name string + repo string + baseDir string sharedNetwork string }{ { - name: "bu1_development", - repo: "bu1-example-app", - baseDir: "../../../4-projects/business_unit_1/%s", + name: "bu1_development", + repo: "bu1-example-app", + baseDir: "../../../4-projects/business_unit_1/%s", sharedNetwork: fmt.Sprintf("vpc-d-svpc%s", networkMode), }, { - name: "bu1_nonproduction", - repo: "bu1-example-app", - baseDir: "../../../4-projects/business_unit_1/%s", + name: "bu1_nonproduction", + repo: "bu1-example-app", + baseDir: "../../../4-projects/business_unit_1/%s", sharedNetwork: fmt.Sprintf("vpc-n-svpc%s", networkMode), }, { - name: "bu1_production", - repo: "bu1-example-app", - baseDir: "../../../4-projects/business_unit_1/%s", + name: "bu1_production", + repo: "bu1-example-app", + baseDir: "../../../4-projects/business_unit_1/%s", sharedNetwork: fmt.Sprintf("vpc-p-svpc%s", networkMode), }, } { @@ -156,9 +156,13 @@ func TestProjects(t *testing.T) { assert.Subset(listApis, restrictedApisEnabled, "APIs should have been enabled") sharedProjectNumber := projects.GetStringOutput("shared_vpc_project_number") + floatingProjectNumber := projects.GetStringOutput("floating_project_number") + peeringProjectNumber := projects.GetStringOutput("peering_project_number") perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", perimeterName, policyID)) assert.NoError(err) assert.True(strings.Contains(perimeter, sharedProjectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s", perimeterName, sharedProjectNumber)) + assert.True(strings.Contains(perimeter, floatingProjectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s", perimeterName, floatingProjectNumber)) + assert.True(strings.Contains(perimeter, peeringProjectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s", perimeterName, peeringProjectNumber)) sharedVPC := gcloud.Runf(t, "compute shared-vpc get-host-project %s --impersonate-service-account %s", projectID, terraformSA) assert.NotEmpty(sharedVPC.Map()) From b492dd06ca171dd655e35dd857486cc719321293 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 29 Aug 2025 09:07:39 -0300 Subject: [PATCH 084/114] fix floating project number output --- 4-projects/modules/base_env/README.md | 1 + 4-projects/modules/base_env/outputs.tf | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/4-projects/modules/base_env/README.md b/4-projects/modules/base_env/README.md index 678dd9677..8abaacdd4 100644 --- a/4-projects/modules/base_env/README.md +++ b/4-projects/modules/base_env/README.md @@ -38,6 +38,7 @@ | access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | bucket | The created storage bucket. | | floating\_project | Project sample floating project. | +| floating\_project\_number | Project number sample floating project. | | iap\_firewall\_tags | The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project. | | keyring | The name of the keyring. | | keys | List of created key names. | diff --git a/4-projects/modules/base_env/outputs.tf b/4-projects/modules/base_env/outputs.tf index a0e33cc12..e7b96de94 100644 --- a/4-projects/modules/base_env/outputs.tf +++ b/4-projects/modules/base_env/outputs.tf @@ -19,8 +19,8 @@ output "floating_project" { value = module.floating_project.project_id } -output "floating_project" { - description = "Project sample floating project." +output "floating_project_number" { + description = "Project number sample floating project." value = module.floating_project.project_number } From 4cda0030db61a63fa95859732c719dfa1ba637ce Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 1 Sep 2025 15:29:45 -0300 Subject: [PATCH 085/114] fix bootstrap test --- test/integration/bootstrap/bootstrap_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/bootstrap/bootstrap_test.go b/test/integration/bootstrap/bootstrap_test.go index d9817529b..3927c4c68 100644 --- a/test/integration/bootstrap/bootstrap_test.go +++ b/test/integration/bootstrap/bootstrap_test.go @@ -164,7 +164,7 @@ func TestBootstrap(t *testing.T) { peeredNetworkName := testutils.GetLastSplitElement(bootstrap.GetStringOutput("cloud_build_peered_network_id"), "/") pool := gcloud.Runf(t, "builds worker-pools describe %s --region %s --project %s", workerPoolName, defaultRegion, cbProjectID) assert.Equal(workerPoolName, pool.Get("name").String(), "pool %s should exist", workerPoolName) - assert.Equal("PUBLIC_EGRESS", pool.Get("privatePoolV1Config.networkConfig.egressOption").String(), "pool %s should have internet access", workerPoolName) + assert.Equal("NO_PUBLIC_EGRESS", pool.Get("privatePoolV1Config.networkConfig.egressOption").String(), "pool %s should have internet access", workerPoolName) assert.Equal("e2-medium", pool.Get("privatePoolV1Config.workerConfig.machineType").String(), "pool %s should have the configured machineType", workerPoolName) assert.Equal("100", pool.Get("privatePoolV1Config.workerConfig.diskSizeGb").String(), "pool %s should have the configured disk size", workerPoolName) assert.Equal(peeredNetworkName, testutils.GetLastSplitElement(pool.Get("privatePoolV1Config.networkConfig.peeredNetwork").String(), "/"), "pool %s should have peered network configured", workerPoolName) From 7cd5b385e518e79eef46058a7c87395e91f7ab34 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 2 Sep 2025 11:52:58 -0300 Subject: [PATCH 086/114] fix retry message network connection --- test/integration/testutils/retry.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) mode change 100644 => 100755 test/integration/testutils/retry.go diff --git a/test/integration/testutils/retry.go b/test/integration/testutils/retry.go old mode 100644 new mode 100755 index d70ca41a6..9a768aec2 --- a/test/integration/testutils/retry.go +++ b/test/integration/testutils/retry.go @@ -41,10 +41,10 @@ var ( ".*Error 403.*Compute Engine API has not been used in project.*": "Compute Engine API not enabled", // Error 400: Service account {} does not exist. - ".*Error 400.*Service account.*does not exist*": "Error setting IAM policy", + ".*Error 400.*Service account.*does not exist.*": "Error setting IAM policy", // Error waiting for creating service network connection. This happens randomly for development, production and non-production environments - ".*Error code 16.*Error waiting for Create Service Networking Connection*": "Request had invalid authentication credentials", + ".*Error code 16.*Error waiting for Create Service Networking Connection.*Expected OAuth 2 access token.*": "Request had invalid authentication credentials", // Error 400: The eTag provided {} does not match the eTag of the current version of the Access Policy, which is {}. ".*Error 400: The eTag provided.*does not match the eTag of the current version of the Access Policy, which is.*": "Conflict during Access Policy configuration.", From 5c2f8c6faec9b5803efa89d9406ed35e6f47a055 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 3 Sep 2025 19:24:00 -0300 Subject: [PATCH 087/114] add directional policies titles --- 1-org/envs/shared/service_control.tf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index edd2b53cd..41e68e412 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -212,9 +212,9 @@ locals { [for p in local.projects : "${p}"] ) - ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env", "billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) + ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) - ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env", "billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) + ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) ingress_policies_map_dry_run = var.required_ingress_rules_app_infra_dry_run ? zipmap( @@ -706,6 +706,7 @@ locals { required_egress_rules = [ { + title = "ER seed -> cicd" from = { identities = [ "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", @@ -728,6 +729,7 @@ locals { } }, { + title = "ER cicd -> scc" from = { identities = [ "serviceAccount:${local.organization_service_account}", From 531bb6bf0449ba57e7be8fee613ac2684f21e9da Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 4 Sep 2025 12:17:01 -0300 Subject: [PATCH 088/114] add rm dry run config when enforced perimeter --- 1-org/envs/shared/service_control.tf | 52 ++++++++++++++++++++++++--- 1-org/modules/service_control/main.tf | 20 ++++++----- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index 41e68e412..c40cbe978 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -177,8 +177,27 @@ locals { module.scc_notifications.project_number, ], local.shared_vpc_projects_numbers)) + projects_dry_run = var.enable_hub_and_spoke ? (concat([ + local.seed_project_number, + module.org_audit_logs.project_number, + module.org_billing_export.project_number, + module.common_kms.project_number, + module.org_secrets.project_number, + module.interconnect.project_number, + module.network_hub[0].project_number, + module.scc_notifications.project_number, + ], local.shared_vpc_projects_numbers)) : (concat([ + local.seed_project_number, + module.org_audit_logs.project_number, + module.org_billing_export.project_number, + module.common_kms.project_number, + module.org_secrets.project_number, + module.interconnect.project_number, + module.scc_notifications.project_number, + ], local.shared_vpc_projects_numbers)) + project_keys = var.enable_hub_and_spoke ? [ - "prj-org-seed", + "prj-b-seed", "prj-org-audit", "prj-org-billing", "prj-org-kms", @@ -190,7 +209,32 @@ locals { "prj-net-d-svpc", "prj-net-n-svpc", ] : [ - "prj-org-seed", + "prj-b-seed", + "prj-org-audit", + "prj-org-billing", + "prj-org-kms", + "prj-org-secrets", + "prj-org-interconnect", + "prj-org-scc", + "prj-net-p-svpc", + "prj-net-d-svpc", + "prj-net-n-svpc", + ] + + project_keys_dry_run = var.enable_hub_and_spoke ? [ + "prj-b-seed", + "prj-org-audit", + "prj-org-billing", + "prj-org-kms", + "prj-org-secrets", + "prj-org-interconnect", + "prj-org-scc", + "prj-net-hub-svpc", + "prj-net-p-svpc", + "prj-net-d-svpc", + "prj-net-n-svpc", + ] : [ + "prj-b-seed", "prj-org-audit", "prj-org-billing", "prj-org-kms", @@ -208,7 +252,7 @@ locals { ) projects_map_dry_run = zipmap( - local.project_keys, + local.project_keys_dry_run, [for p in local.projects : "${p}"] ) @@ -801,7 +845,7 @@ module "service_control" { "serviceAccount:${local.environment_service_account}", ], var.perimeter_additional_members)) resources_dry_run = concat(values(local.projects_map_dry_run), var.resources_dry_run) - resource_keys_dry_run = local.project_keys + resource_keys_dry_run = local.project_keys_dry_run ingress_policies_keys_dry_run = local.ingress_policies_keys_dry_run egress_policies_keys_dry_run = local.egress_policies_keys_dry_run ingress_policies_keys = local.ingress_policies_keys diff --git a/1-org/modules/service_control/main.tf b/1-org/modules/service_control/main.tf index b0c4a8fe0..131794244 100644 --- a/1-org/modules/service_control/main.tf +++ b/1-org/modules/service_control/main.tf @@ -36,6 +36,8 @@ module "access_level" { } module "access_level_dry_run" { + count = !var.enforce_vpcsc ? 1 : 0 + source = "terraform-google-modules/vpc-service-controls/google//modules/access_level" version = "~> 7.1.3" @@ -65,15 +67,15 @@ module "regular_service_perimeter" { egress_policies_keys = var.enforce_vpcsc ? var.egress_policies_keys : [] # configurations for a perimeter in dry run mode. - resources_dry_run = var.resources_dry_run - resource_keys_dry_run = var.resource_keys_dry_run - access_levels_dry_run = [module.access_level_dry_run.name] - restricted_services_dry_run = var.restricted_services_dry_run - vpc_accessible_services_dry_run = ["*"] - ingress_policies_dry_run = var.ingress_policies_dry_run - ingress_policies_keys_dry_run = var.ingress_policies_keys_dry_run - egress_policies_dry_run = var.egress_policies_dry_run - egress_policies_keys_dry_run = var.egress_policies_keys_dry_run + resources_dry_run = !var.enforce_vpcsc ? var.resources_dry_run : [] + resource_keys_dry_run = !var.enforce_vpcsc ? var.resource_keys_dry_run : [] + access_levels_dry_run = !var.enforce_vpcsc && length(module.access_level_dry_run) > 0 ? [module.access_level_dry_run[0].name] : [] + restricted_services_dry_run = !var.enforce_vpcsc ? var.restricted_services_dry_run : [] + vpc_accessible_services_dry_run = !var.enforce_vpcsc ? ["*"] : [] + ingress_policies_dry_run = !var.enforce_vpcsc ? var.ingress_policies_dry_run : [] + ingress_policies_keys_dry_run = !var.enforce_vpcsc ? var.ingress_policies_keys_dry_run : [] + egress_policies_dry_run = !var.enforce_vpcsc ? var.egress_policies_dry_run : [] + egress_policies_keys_dry_run = !var.enforce_vpcsc ? var.egress_policies_keys_dry_run : [] } resource "time_sleep" "wait_vpc_sc_propagation" { From f5661e3ed8a30839a2e0fc087ffd65204ddaa126 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 4 Sep 2025 14:50:59 -0300 Subject: [PATCH 089/114] fix directional policies variables integration tests --- test/integration/org/org_test.go | 44 ++------------------------------ 1 file changed, 2 insertions(+), 42 deletions(-) mode change 100644 => 100755 test/integration/org/org_test.go diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go old mode 100644 new mode 100755 index 03ea08d55..e2d1d39c9 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -39,49 +39,9 @@ func TestOrg(t *testing.T) { backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") - ingressPolicies := []map[string]interface{}{ - { - "from": map[string]interface{}{ - "sources": map[string][]string{ - "access_levels": {"*"}, - }, - "identity_type": "ANY_IDENTITY", - }, - "to": map[string]interface{}{ - "resources": []string{"*"}, - "operations": map[string]map[string][]string{ - "storage.googleapis.com": { - "methods": { - "google.storage.objects.get", - "google.storage.objects.list", - }, - }, - }, - }, - }, - } + ingressPolicies := []map[string]interface{}{} - egressPolicies := []map[string]interface{}{ - { - "from": map[string]interface{}{ - "sources": map[string][]string{ - "access_levels": {"*"}, - }, - "identity_type": "ANY_IDENTITY", - }, - "to": map[string]interface{}{ - "resources": []string{"*"}, - "operations": map[string]map[string][]string{ - "storage.googleapis.com": { - "methods": { - "google.storage.objects.get", - "google.storage.objects.list", - }, - }, - }, - }, - }, - } + egressPolicies := []map[string]interface{}{} terraformSA := bootstrap.GetStringOutput("organization_step_terraform_service_account_email") From b73de7fac28b8d6b0a69b34f36b63d0c6202f424 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 4 Sep 2025 17:14:43 -0300 Subject: [PATCH 090/114] fix json format commands --- test/integration/org/org_test.go | 6 +++--- test/integration/projects-shared/projects_shared_test.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) mode change 100644 => 100755 test/integration/projects-shared/projects_shared_test.go diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go index e2d1d39c9..55b4257a2 100755 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -526,7 +526,7 @@ func TestOrg(t *testing.T) { // verify seed project in perimeter sharedProjectNumber := bootstrap.GetStringOutput("seed_project_number") - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) projectFormat := fmt.Sprintf("projects/%s", sharedProjectNumber) perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) @@ -545,7 +545,7 @@ func TestOrg(t *testing.T) { assert.Equal("ACTIVE", projects[0].Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) numberOutput := strings.ReplaceAll(hubAndSpokeProjectOutput, "_id", "_number") // "net_hub_project_number" projectNumber := org.GetStringOutput(numberOutput) - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) projectFormat := fmt.Sprintf("projects/%s", projectNumber) perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) @@ -643,7 +643,7 @@ func TestOrg(t *testing.T) { prj := gcloud.Runf(t, "projects describe %s", projectID) assert.Equal(projectID, prj.Get("projectId").String(), fmt.Sprintf("project %s should exist", projectID)) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) projectFormat := fmt.Sprintf("projects/%s", projectNumber) perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) diff --git a/test/integration/projects-shared/projects_shared_test.go b/test/integration/projects-shared/projects_shared_test.go old mode 100644 new mode 100755 index 5136a7aa1..c64acd61c --- a/test/integration/projects-shared/projects_shared_test.go +++ b/test/integration/projects-shared/projects_shared_test.go @@ -98,7 +98,7 @@ func TestProjectsShared(t *testing.T) { assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) projectFormat := fmt.Sprintf("projects/%s", projectNumber) - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) spec := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(spec, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) From 38c1b04049da67e6f87eaec3294169daac9da089 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 5 Sep 2025 13:03:12 -0300 Subject: [PATCH 091/114] add --format --- test/integration/org/org_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go index 55b4257a2..7d4e0e443 100755 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -262,7 +262,7 @@ func TestOrg(t *testing.T) { servicePerimeterLink := fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", policyID, org.GetStringOutput("service_perimeter_name")) accessLevel := fmt.Sprintf("accessPolicies/%s/accessLevels/%s", policyID, org.GetStringOutput("access_level_name_dry_run")) - servicePerimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", servicePerimeterLink, policyID)) + servicePerimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID)) assert.NoError(err) perimeterName := org.GetStringOutput("service_perimeter_name") assert.True(strings.Contains(servicePerimeter, perimeterName), fmt.Sprintf("service perimeter %s should exist", perimeterName)) From 9678337d504319d54fc7ec331800c0d3b3317dea Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 8 Sep 2025 15:01:50 -0300 Subject: [PATCH 092/114] fix gcloud perimeter describe command --- test/integration/envs/envs_test.go | 2 +- test/integration/projects-shared/projects_shared_test.go | 2 +- test/integration/projects/projects_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 test/integration/envs/envs_test.go mode change 100644 => 100755 test/integration/projects/projects_test.go diff --git a/test/integration/envs/envs_test.go b/test/integration/envs/envs_test.go old mode 100644 new mode 100755 index be3e4e9bf..4c5e28ab4 --- a/test/integration/envs/envs_test.go +++ b/test/integration/envs/envs_test.go @@ -127,7 +127,7 @@ func TestEnvs(t *testing.T) { assert.Equal(projectID, prj.Get("projectId").String(), fmt.Sprintf("project %s should exist", projectID)) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) - perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", perimeterName, policyID)) + perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters describe %s --policy %s", perimeterName, policyID)) assert.NoError(err) assert.True(strings.Contains(perimeter, projectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s (number)", perimeterName, projectNumber)) diff --git a/test/integration/projects-shared/projects_shared_test.go b/test/integration/projects-shared/projects_shared_test.go index c64acd61c..069bca1f3 100755 --- a/test/integration/projects-shared/projects_shared_test.go +++ b/test/integration/projects-shared/projects_shared_test.go @@ -98,7 +98,7 @@ func TestProjectsShared(t *testing.T) { assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) projectFormat := fmt.Sprintf("projects/%s", projectNumber) - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters describe %s --policy %s --format=json", servicePerimeterLink, policyID) spec := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(spec, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) diff --git a/test/integration/projects/projects_test.go b/test/integration/projects/projects_test.go old mode 100644 new mode 100755 index f155be803..f6588cf38 --- a/test/integration/projects/projects_test.go +++ b/test/integration/projects/projects_test.go @@ -158,7 +158,7 @@ func TestProjects(t *testing.T) { sharedProjectNumber := projects.GetStringOutput("shared_vpc_project_number") floatingProjectNumber := projects.GetStringOutput("floating_project_number") peeringProjectNumber := projects.GetStringOutput("peering_project_number") - perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", perimeterName, policyID)) + perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters describe %s --policy %s", perimeterName, policyID)) assert.NoError(err) assert.True(strings.Contains(perimeter, sharedProjectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s", perimeterName, sharedProjectNumber)) assert.True(strings.Contains(perimeter, floatingProjectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s", perimeterName, floatingProjectNumber)) From a7ef5906443c042f03bd70f1670e9fe0b8e21c66 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 8 Sep 2025 16:12:31 -0300 Subject: [PATCH 093/114] fix integration tests --- test/integration/org/org_test.go | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go index 7d4e0e443..8066022b0 100755 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -259,10 +259,9 @@ func TestOrg(t *testing.T) { // check tags applied to common and bootstrap folder commonConfig := terraform.OutputMap(t, bootstrap.GetTFOptions(), "common_config") bootstrapFolder := testutils.GetLastSplitElement(commonConfig["bootstrap_folder_name"], "/") - servicePerimeterLink := fmt.Sprintf("accessPolicies/%s/servicePerimeters/%s", policyID, org.GetStringOutput("service_perimeter_name")) accessLevel := fmt.Sprintf("accessPolicies/%s/accessLevels/%s", policyID, org.GetStringOutput("access_level_name_dry_run")) - servicePerimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID)) + servicePerimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters describe %s --policy %s", servicePerimeterLink, policyID)) assert.NoError(err) perimeterName := org.GetStringOutput("service_perimeter_name") assert.True(strings.Contains(servicePerimeter, perimeterName), fmt.Sprintf("service perimeter %s should exist", perimeterName)) @@ -526,7 +525,7 @@ func TestOrg(t *testing.T) { // verify seed project in perimeter sharedProjectNumber := bootstrap.GetStringOutput("seed_project_number") - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters describe %s --policy %s", servicePerimeterLink, policyID) projectFormat := fmt.Sprintf("projects/%s", sharedProjectNumber) perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) @@ -545,7 +544,7 @@ func TestOrg(t *testing.T) { assert.Equal("ACTIVE", projects[0].Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) numberOutput := strings.ReplaceAll(hubAndSpokeProjectOutput, "_id", "_number") // "net_hub_project_number" projectNumber := org.GetStringOutput(numberOutput) - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters describe %s --policy %s", servicePerimeterLink, policyID) projectFormat := fmt.Sprintf("projects/%s", projectNumber) perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) @@ -606,7 +605,7 @@ func TestOrg(t *testing.T) { prj := gcloud.Runf(t, "projects describe %s", projectID) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) projectNumber := prj.Get("projectNumber").String() - perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters dry-run describe %s --policy %s", servicePerimeterLink, policyID)) + perimeter, err := gcloud.RunCmdE(t, fmt.Sprintf("access-context-manager perimeters describe %s --policy %s", servicePerimeterLink, policyID)) assert.NoError(err) assert.True(strings.Contains(perimeter, projectNumber), fmt.Sprintf("dry-run service perimeter %s should contain project %s (number: %s)", perimeterName, projectID, projectNumber)) enabledAPIS := gcloud.Runf(t, "services list --project %s", projectID).Array() @@ -643,7 +642,7 @@ func TestOrg(t *testing.T) { prj := gcloud.Runf(t, "projects describe %s", projectID) assert.Equal(projectID, prj.Get("projectId").String(), fmt.Sprintf("project %s should exist", projectID)) assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) - perimeter := gcloud.Runf(t, "access-context-manager perimeters dry-run describe %s --policy %s --format=json", servicePerimeterLink, policyID) + perimeter := gcloud.Runf(t, "access-context-manager perimeters describe %s --policy %s", servicePerimeterLink, policyID) projectFormat := fmt.Sprintf("projects/%s", projectNumber) perimeterResources := utils.GetResultStrSlice(perimeter.Get("spec.resources").Array()) assert.Contains(perimeterResources, projectFormat, fmt.Sprintf("dry-run service perimeter %s should contain %s", perimeterName, projectFormat)) From 5a3689e4893e609dc065eeb8dcf61120ba8b3263 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Wed, 10 Sep 2025 14:25:33 -0300 Subject: [PATCH 094/114] add env_secrets_project_number output in 2-envs --- 2-environments/envs/development/README.md | 1 + 2-environments/envs/development/outputs.tf | 5 +++++ 2-environments/envs/nonproduction/README.md | 1 + 2-environments/envs/nonproduction/outputs.tf | 5 +++++ 2-environments/envs/production/README.md | 2 +- 2-environments/envs/production/outputs.tf | 2 +- 6 files changed, 14 insertions(+), 2 deletions(-) diff --git a/2-environments/envs/development/README.md b/2-environments/envs/development/README.md index 24b7a7c63..7fbf194e7 100644 --- a/2-environments/envs/development/README.md +++ b/2-environments/envs/development/README.md @@ -16,5 +16,6 @@ | env\_kms\_project\_id | Project for environment Cloud Key Management Service (KMS). | | env\_kms\_project\_number | Project Number for environment Cloud Key Management Service (KMS). | | env\_secrets\_project\_id | Project for environment related secrets. | +| env\_secrets\_project\_number | Project number for environment related secrets. | diff --git a/2-environments/envs/development/outputs.tf b/2-environments/envs/development/outputs.tf index 946657d94..d877d5ae7 100644 --- a/2-environments/envs/development/outputs.tf +++ b/2-environments/envs/development/outputs.tf @@ -24,6 +24,11 @@ output "env_secrets_project_id" { value = module.env.env_secrets_project_id } +output "env_secrets_project_number" { + description = "Project number for environment related secrets." + value = module.env.env_secrets_project_number +} + output "env_kms_project_id" { description = "Project for environment Cloud Key Management Service (KMS)." value = module.env.env_kms_project_id diff --git a/2-environments/envs/nonproduction/README.md b/2-environments/envs/nonproduction/README.md index 24b7a7c63..7fbf194e7 100644 --- a/2-environments/envs/nonproduction/README.md +++ b/2-environments/envs/nonproduction/README.md @@ -16,5 +16,6 @@ | env\_kms\_project\_id | Project for environment Cloud Key Management Service (KMS). | | env\_kms\_project\_number | Project Number for environment Cloud Key Management Service (KMS). | | env\_secrets\_project\_id | Project for environment related secrets. | +| env\_secrets\_project\_number | Project number for environment related secrets. | diff --git a/2-environments/envs/nonproduction/outputs.tf b/2-environments/envs/nonproduction/outputs.tf index 1ca8087d6..9609bf673 100644 --- a/2-environments/envs/nonproduction/outputs.tf +++ b/2-environments/envs/nonproduction/outputs.tf @@ -24,6 +24,11 @@ output "env_secrets_project_id" { value = module.env.env_secrets_project_id } +output "env_secrets_project_number" { + description = "Project number for environment related secrets." + value = module.env.env_secrets_project_number +} + output "env_kms_project_id" { description = "Project for environment Cloud Key Management Service (KMS)." value = module.env.env_kms_project_id diff --git a/2-environments/envs/production/README.md b/2-environments/envs/production/README.md index f6f936b8f..2d97586d3 100644 --- a/2-environments/envs/production/README.md +++ b/2-environments/envs/production/README.md @@ -18,7 +18,7 @@ | env\_kms\_project\_id | Project for environment Cloud Key Management Service (KMS). | | env\_kms\_project\_number | Project Number for environment Cloud Key Management Service (KMS). | | env\_secrets\_project\_id | Project for environment related secrets. | -| env\_secrets\_project\_number | Project for environment related secrets. | +| env\_secrets\_project\_number | Project number for environment related secrets. | diff --git a/2-environments/envs/production/outputs.tf b/2-environments/envs/production/outputs.tf index 4aaae7585..a5b7956e1 100644 --- a/2-environments/envs/production/outputs.tf +++ b/2-environments/envs/production/outputs.tf @@ -25,7 +25,7 @@ output "env_secrets_project_id" { } output "env_secrets_project_number" { - description = "Project for environment related secrets." + description = "Project number for environment related secrets." value = module.env.env_secrets_project_number } From ec54c53ff3245a9e0d005b3020e9e4d6df8bea4a Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 11 Sep 2025 19:44:47 -0300 Subject: [PATCH 095/114] rm access context manager variable references in bootstrap README --- 0-bootstrap/README-GitHub.md | 6 ++---- 0-bootstrap/README-GitLab.md | 6 ++---- 0-bootstrap/README-Jenkins.md | 6 ++---- 0-bootstrap/README-Terraform-Cloud.md | 6 ++---- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/0-bootstrap/README-GitHub.md b/0-bootstrap/README-GitHub.md index eb2571fea..1d70b8c24 100644 --- a/0-bootstrap/README-GitHub.md +++ b/0-bootstrap/README-GitHub.md @@ -565,12 +565,11 @@ or go to [Deploying step 3-networks-hub-and-spoke](#deploying-step-3-networks-hu chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update the file `production.auto.tfvars` with the values for the `target_name_server_addresses`. @@ -762,12 +761,11 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv shared.auto.example.tfvars shared.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your GCP environment. diff --git a/0-bootstrap/README-GitLab.md b/0-bootstrap/README-GitLab.md index 1b5a4d205..e3d67a2c9 100644 --- a/0-bootstrap/README-GitLab.md +++ b/0-bootstrap/README-GitLab.md @@ -568,12 +568,11 @@ or go to [Deploying step 3-networks-hub-and-spoke](#deploying-step-3-networks-hu chmod 755 ./*.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update the file `production.auto.tfvars` with the values for the `target_name_server_addresses`. @@ -742,12 +741,11 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th chmod 755 ./*.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv shared.auto.example.tfvars shared.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your GCP environment. diff --git a/0-bootstrap/README-Jenkins.md b/0-bootstrap/README-Jenkins.md index b1bd39a07..50061f549 100644 --- a/0-bootstrap/README-Jenkins.md +++ b/0-bootstrap/README-Jenkins.md @@ -599,12 +599,11 @@ Here you will configure a VPN Network tunnel to enable connectivity between the sed -i'' -e "s/CICD_PROJECT_ID/${CICD_PROJECT_ID}/" ./Jenkinsfile ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](../3-networks-svpc/envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. @@ -752,12 +751,11 @@ Here you will configure a VPN Network tunnel to enable connectivity between the sed -i'' -e "s/CICD_PROJECT_ID/${CICD_PROJECT_ID}/" ./Jenkinsfile ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv shared.auto.example.tfvars shared.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](../3-networks-hub-and-spoke/envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. diff --git a/0-bootstrap/README-Terraform-Cloud.md b/0-bootstrap/README-Terraform-Cloud.md index 53b17c734..a2b517ba0 100644 --- a/0-bootstrap/README-Terraform-Cloud.md +++ b/0-bootstrap/README-Terraform-Cloud.md @@ -476,12 +476,11 @@ or go to [Deploying step 3-networks-hub-and-spoke](#deploying-step-3-networks-hu chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `production.auto.example.tfvars` to `production.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `production.auto.example.tfvars` to `production.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv production.auto.example.tfvars production.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update the file `production.auto.tfvars` with the values for the `target_name_server_addresses`. @@ -639,12 +638,11 @@ An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set with th chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv shared.auto.example.tfvars shared.auto.tfvars - mv access_context.auto.example.tfvars access_context.auto.tfvars ``` 1. Update `common.auto.tfvars` file with values from your GCP environment. From 834e448bfda1e00bac1fc8716bc07b3b47c19005 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 11 Sep 2025 19:45:40 -0300 Subject: [PATCH 096/114] rm access context manager varible in test files --- test/disable_tf_files.sh | 8 -------- test/restore_tf_files.sh | 13 ------------- 2 files changed, 21 deletions(-) mode change 100644 => 100755 test/restore_tf_files.sh diff --git a/test/disable_tf_files.sh b/test/disable_tf_files.sh index 3f5438622..0be5f06c7 100755 --- a/test/disable_tf_files.sh +++ b/test/disable_tf_files.sh @@ -28,11 +28,6 @@ function networks(){ mv $network_dir/envs/production/production.auto.tfvars $network_dir/envs/production/production.auto.tfvars.disabled fi - # disable access_context.auto.tfvars in main module - mv $network_dir/envs/development/access_context.auto.tfvars $network_dir/envs/development/access_context.auto.tfvars.disabled - mv $network_dir/envs/nonproduction/access_context.auto.tfvars $network_dir/envs/nonproduction/access_context.auto.tfvars.disabled - mv $network_dir/envs/production/access_context.auto.tfvars $network_dir/envs/production/access_context.auto.tfvars.disabled - # disable common.auto.tfvars in main module mv $network_dir/envs/development/common.auto.tfvars $network_dir/envs/development/common.auto.tfvars.disabled mv $network_dir/envs/nonproduction/common.auto.tfvars $network_dir/envs/nonproduction/common.auto.tfvars.disabled @@ -50,9 +45,6 @@ function shared(){ network_dir="3-networks-svpc" fi - # disable access_context.auto.tfvars in main module - mv $network_dir/envs/shared/access_context.auto.tfvars $network_dir/envs/shared/access_context.auto.tfvars.disabled - # disable common.auto.tfvars in main module mv $network_dir/envs/shared/common.auto.tfvars $network_dir/envs/shared/common.auto.tfvars.disabled } diff --git a/test/restore_tf_files.sh b/test/restore_tf_files.sh old mode 100644 new mode 100755 index c089f459c..6ec7cbf04 --- a/test/restore_tf_files.sh +++ b/test/restore_tf_files.sh @@ -45,11 +45,6 @@ function networks(){ mv $network_dir/envs/nonproduction/backend.tf.disabled $network_dir/envs/nonproduction/backend.tf mv $network_dir/envs/production/backend.tf.disabled $network_dir/envs/production/backend.tf - # restore access_context.auto.tfvars in main module - mv $network_dir/envs/development/access_context.auto.tfvars.disabled $network_dir/envs/development/access_context.auto.tfvars - mv $network_dir/envs/nonproduction/access_context.auto.tfvars.disabled $network_dir/envs/nonproduction/access_context.auto.tfvars - mv $network_dir/envs/production/access_context.auto.tfvars.disabled $network_dir/envs/production/access_context.auto.tfvars - # restore common.auto.tfvars in main module mv $network_dir/envs/development/common.auto.tfvars.disabled $network_dir/envs/development/common.auto.tfvars mv $network_dir/envs/nonproduction/common.auto.tfvars.disabled $network_dir/envs/nonproduction/common.auto.tfvars @@ -70,9 +65,6 @@ function shared(){ # restore backend configs in main module mv $network_dir/envs/shared/backend.tf.disabled $network_dir/envs/shared/backend.tf - # restore access_context.auto.tfvars in main module - mv $network_dir/envs/shared/access_context.auto.tfvars.disabled $network_dir/envs/shared/access_context.auto.tfvars - # restore common.auto.tfvars in main module mv $network_dir/envs/shared/common.auto.tfvars.disabled $network_dir/envs/shared/common.auto.tfvars } @@ -84,11 +76,6 @@ function projects(){ mv 4-projects/business_unit_1/production/backend.tf.disabled 4-projects/business_unit_1/production/backend.tf mv 4-projects/business_unit_1/shared/backend.tf.disabled 4-projects/business_unit_1/shared/backend.tf - # restore access_context.auto.tfvars in main module - mv 4-projects/business_unit_1/development/access_context.auto.tfvars.disabled 4-projects/business_unit_1/development/access_context.auto.tfvars - mv 4-projects/business_unit_1/nonproduction/access_context.auto.tfvars.disabled 4-projects/business_unit_1/nonproduction/access_context.auto.tfvars - mv 4-projects/business_unit_1/production/access_context.auto.tfvars.disabled 4-projects/business_unit_1/production/access_context.auto.tfvars - # restore business_unit_1.auto.tfvars in main module mv 4-projects/business_unit_1/development/business_unit_1.auto.tfvars.disabled 4-projects/business_unit_1/development/business_unit_1.auto.tfvars mv 4-projects/business_unit_1/nonproduction/business_unit_1.auto.tfvars.disabled 4-projects/business_unit_1/nonproduction/business_unit_1.auto.tfvars From 98d570e3a6b9ae83872359ac771398066765f5fc Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 11 Sep 2025 19:46:14 -0300 Subject: [PATCH 097/114] rm access context manager variable references in hub and spoke README --- 3-networks-hub-and-spoke/README.md | 36 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/3-networks-hub-and-spoke/README.md b/3-networks-hub-and-spoke/README.md index 3c3e14aa6..2164b43fc 100644 --- a/3-networks-hub-and-spoke/README.md +++ b/3-networks-hub-and-spoke/README.md @@ -159,14 +159,14 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get chmod 755 ./tf-wrapper.sh ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +2. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars mv shared.auto.example.tfvars shared.auto.tfvars ``` -1. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. +3. Update `common.auto.tfvars` file with values from your environment and bootstrap. See any of the envs folder [README.md](./envs/production/README.md) files for additional information on the values in the `common.auto.tfvars` file. Update `shared.auto.tfvars` file with the `target_name_server_addresses`. Use `terraform output` to get the backend bucket value from 0-bootstrap output. @@ -177,16 +177,16 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get sed -i'' -e "s/REMOTE_STATE_BUCKET/${backend_bucket}/" ./common.auto.tfvars ``` -2. Commit changes +4. Commit changes ```bash git add . git commit -m 'Initialize networks repo' ``` -3. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. -4. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. -5. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. +5. You must manually plan and apply the `shared` environment (only once) since the `development`, `nonproduction` and `production` environments depend on it. +6. To use the `validate` option of the `tf-wrapper.sh` script, please follow the [instructions](https://cloud.google.com/docs/terraform/policy-validation/validate-policies#install) to install the terraform-tools component. +7. Use `terraform output` to get the Cloud Build project ID and the networks step Terraform Service Account from 0-bootstrap output. An environment variable `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` will be set using the Terraform Service Account to enable impersonation. ```bash export CLOUD_BUILD_PROJECT_ID=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw cloudbuild_project_id) @@ -196,26 +196,26 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get echo ${GOOGLE_IMPERSONATE_SERVICE_ACCOUNT} ``` -6. Run `init` and `plan` and review output for environment shared. +8. Run `init` and `plan` and review output for environment shared. ```bash ./tf-wrapper.sh init shared ./tf-wrapper.sh plan shared ``` -7. Run `validate` and check for violations. +9. Run `validate` and check for violations. ```bash ./tf-wrapper.sh validate shared $(pwd)/../gcp-policies ${CLOUD_BUILD_PROJECT_ID} ``` -8. Run `apply` shared. +10. Run `apply` shared. ```bash ./tf-wrapper.sh apply shared ``` -9. Push your plan branch to trigger a plan for all environments. Because the +11. Push your plan branch to trigger a plan for all environments. Because the _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch)), pushing your _plan_ branch triggers _terraform plan_ but not _terraform apply_. Review the plan output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID @@ -223,7 +223,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push --set-upstream origin plan ``` -10. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +12. Merge changes to production. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -231,8 +231,8 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin production ``` -11. After production has been applied, apply development. -12. Merge changes to development. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +13. After production has been applied, apply development. +14. Merge changes to development. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -240,8 +240,8 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin development ``` -13. After development has been applied, apply nonproduction. -14. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), +15. After development has been applied, apply nonproduction. +16. Merge changes to nonproduction. Because this is a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing to this branch triggers both _terraform plan_ and _terraform apply_. Review the apply output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash @@ -249,13 +249,13 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get git push origin nonproduction ``` -15. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. +17. Before executing the next steps, unset the `GOOGLE_IMPERSONATE_SERVICE_ACCOUNT` environment variable. ```bash unset GOOGLE_IMPERSONATE_SERVICE_ACCOUNT ``` -16. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. +18. You can now move to the instructions in the [4-projects](../4-projects/README.md) step. ### Deploying with Jenkins @@ -288,7 +288,7 @@ See `0-bootstrap` [README-GitHub.md](../0-bootstrap/README-GitHub.md#deploying-s git checkout -b production ``` -1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars`. +1. Rename `common.auto.example.tfvars` to `common.auto.tfvars`, and rename `shared.auto.example.tfvars` to `shared.auto.tfvars`. ```bash mv common.auto.example.tfvars common.auto.tfvars From 0ffcbe0729f9722e334e5f896a8ccb98eb1ffd76 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 11 Sep 2025 20:23:15 -0300 Subject: [PATCH 098/114] add warning to directional policies dry run variables --- 4-projects/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/4-projects/README.md b/4-projects/README.md index a0ad86cd9..52a39ab11 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -591,3 +591,7 @@ If you received any errors or made any changes to the Terraform config or any `. ``` 1. You can now move to the instructions in the [5-app-infra](../5-app-infra/README.md) step. + +## Warning + +If you previously enabled the dry-run variables `required_ingress_rules_app_infra_dry_run` and `required_egress_rules_app_infra_dry_run`, you must **disable both of them before running the 4-projects step in enforced mode**. Once enforced mode is activated and the **4-projects** step is executed, the projects created in that step are removed from the dry-run perimeter. Keeping these dry-run variables active creates conflicts, because they define rules for projects that will no longer be part of the dry-run perimeter after this transition. \ No newline at end of file From b3490ab12be04cfff0799c58e9f8fe0088c56d8b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 11 Sep 2025 20:29:51 -0300 Subject: [PATCH 099/114] add warning to disable dry run directional rules variable before enforced mode --- 1-org/envs/shared/terraform.example.tfvars | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/1-org/envs/shared/terraform.example.tfvars b/1-org/envs/shared/terraform.example.tfvars index 6d9e85f98..904e5d2bb 100644 --- a/1-org/envs/shared/terraform.example.tfvars +++ b/1-org/envs/shared/terraform.example.tfvars @@ -46,6 +46,10 @@ billing_export_dataset_location = "US" access_context_manager_policy_id = ACCESS_CONTEXT_MANAGER_ID +// If you choose to enable enforced mode, make sure to disable the dry-run variables +// required_ingress_rules_app_infra_dry_run and required_egress_rules_app_infra_dry_run +// before running the 4-projects step + //required_egress_rules_app_infra_dry_run = true //required_egress_rules_app_infra = true From 88fff0baaa7f6fab38b28c672a9e321bafddf56e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Fri, 12 Sep 2025 18:38:57 -0300 Subject: [PATCH 100/114] fix lint --- 3-networks-hub-and-spoke/README.md | 2 +- 4-projects/README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/3-networks-hub-and-spoke/README.md b/3-networks-hub-and-spoke/README.md index 2164b43fc..611157b69 100644 --- a/3-networks-hub-and-spoke/README.md +++ b/3-networks-hub-and-spoke/README.md @@ -216,7 +216,7 @@ Run `terraform output cloudbuild_project_id` in the `0-bootstrap` folder to get ``` 11. Push your plan branch to trigger a plan for all environments. Because the - _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch)), pushing your _plan_ + _plan_ branch is not a [named environment branch](../docs/FAQ.md#what-is-a-named-branch), pushing your _plan_ branch triggers _terraform plan_ but not _terraform apply_. Review the plan output in your Cloud Build project https://console.cloud.google.com/cloud-build/builds;region=DEFAULT_REGION?project=YOUR_CLOUD_BUILD_PROJECT_ID ```bash diff --git a/4-projects/README.md b/4-projects/README.md index 52a39ab11..f38d1a0e3 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -594,4 +594,4 @@ If you received any errors or made any changes to the Terraform config or any `. ## Warning -If you previously enabled the dry-run variables `required_ingress_rules_app_infra_dry_run` and `required_egress_rules_app_infra_dry_run`, you must **disable both of them before running the 4-projects step in enforced mode**. Once enforced mode is activated and the **4-projects** step is executed, the projects created in that step are removed from the dry-run perimeter. Keeping these dry-run variables active creates conflicts, because they define rules for projects that will no longer be part of the dry-run perimeter after this transition. \ No newline at end of file +If you previously enabled the dry-run variables `required_ingress_rules_app_infra_dry_run` and `required_egress_rules_app_infra_dry_run`, you must **disable both of them before running the 4-projects step in enforced mode**. Once enforced mode is activated and the **4-projects** step is executed, the projects created in that step are removed from the dry-run perimeter. Keeping these dry-run variables active creates conflicts, because they define rules for projects that will no longer be part of the dry-run perimeter after this transition. From 14008d24c88165d086a84917272cd632af9ce52a Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 18 Sep 2025 09:54:55 -0300 Subject: [PATCH 101/114] rm access context and perimeter variables in shared test --- test/integration/shared/shared_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/integration/shared/shared_test.go b/test/integration/shared/shared_test.go index 1b1a73016..5447983aa 100644 --- a/test/integration/shared/shared_test.go +++ b/test/integration/shared/shared_test.go @@ -58,8 +58,6 @@ func TestShared(t *testing.T) { } var tfdDir string if isHubAndSpokeMode(t) { - vars["access_context_manager_policy_id"] = policyID - vars["perimeter_additional_members"] = []string{} tfdDir = "../../../3-networks-hub-and-spoke/envs/shared" } else { tfdDir = "../../../3-networks-svpc/envs/shared" From 6ec4b450e38d0d5765c2e0300aeaab88380dbc8d Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 18 Sep 2025 13:15:34 -0300 Subject: [PATCH 102/114] updt bootstrap module --- 0-bootstrap/cb.tf | 6 +++--- 4-projects/modules/infra_pipelines/main.tf | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/0-bootstrap/cb.tf b/0-bootstrap/cb.tf index 216442c38..3a3dff7d9 100644 --- a/0-bootstrap/cb.tf +++ b/0-bootstrap/cb.tf @@ -84,7 +84,7 @@ module "gcp_projects_state_bucket" { module "tf_source" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_source" - version = "~> 11.0" + version = "~> 11.0.1" org_id = var.org_id folder_id = google_folder.bootstrap.id @@ -164,7 +164,7 @@ module "tf_private_pool" { module "tf_cloud_builder" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_builder" - version = "~> 11.0" + version = "~> 11.0.1" project_id = module.tf_source.cloudbuild_project_id dockerfile_repo_uri = module.tf_source.csr_repos[local.cloudbuilder_repo].url @@ -216,7 +216,7 @@ module "build_terraform_image" { module "tf_workspace" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace" - version = "~> 11.0" + version = "~> 11.0.1" for_each = local.granular_sa project_id = module.tf_source.cloudbuild_project_id diff --git a/4-projects/modules/infra_pipelines/main.tf b/4-projects/modules/infra_pipelines/main.tf index ab0da04ea..27521165b 100644 --- a/4-projects/modules/infra_pipelines/main.tf +++ b/4-projects/modules/infra_pipelines/main.tf @@ -55,7 +55,7 @@ resource "google_storage_bucket" "cloudbuild_bucket" { module "tf_workspace" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace" - version = "~> 11.0" + version = "~> 11.0.1" for_each = toset(var.app_infra_repos) From dd27a7e2d9b87be9101df8076fdb2f80a262109e Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 18 Sep 2025 17:47:22 -0300 Subject: [PATCH 103/114] fix service perimeter name in projects_test.go --- test/integration/projects/projects_test.go | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/test/integration/projects/projects_test.go b/test/integration/projects/projects_test.go index f6588cf38..a11ab3525 100755 --- a/test/integration/projects/projects_test.go +++ b/test/integration/projects/projects_test.go @@ -100,23 +100,14 @@ func TestProjects(t *testing.T) { t.Parallel() env := testutils.GetLastSplitElement(tt.name, "_") - netVars := map[string]interface{}{ - "access_context_manager_policy_id": policyID, - } // networks created to retrieve output from the network step for this environment - var networkTFDir string - if networkMode == "" { - networkTFDir = "../../../3-networks-svpc/envs/%s" - } else { - networkTFDir = "../../../3-networks-hub-and-spoke/envs/%s" - } - networks := tft.NewTFBlueprintTest(t, - tft.WithTFDir(fmt.Sprintf(networkTFDir, env)), - tft.WithVars(netVars), + org := tft.NewTFBlueprintTest(t, + tft.WithTFDir("../../../1-org/envs/shared"), ) - perimeterName := networks.GetStringOutput("service_perimeter_name") + + perimeterName := org.GetStringOutput("service_perimeter_name") shared := tft.NewTFBlueprintTest(t, tft.WithTFDir(fmt.Sprintf(tt.baseDir, "shared")), From b36fc8d242a2780e6c0a582ebe7ec520d1a02239 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 18 Sep 2025 17:58:33 -0300 Subject: [PATCH 104/114] upd bootstrap module --- 0-bootstrap/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/0-bootstrap/main.tf b/0-bootstrap/main.tf index 81d7e634f..c33e3e415 100644 --- a/0-bootstrap/main.tf +++ b/0-bootstrap/main.tf @@ -45,7 +45,7 @@ resource "google_folder" "bootstrap" { module "seed_bootstrap" { source = "terraform-google-modules/bootstrap/google" - version = "~> 11.0" + version = "~> 11.0.1" org_id = var.org_id folder_id = google_folder.bootstrap.id From a054a54580dca08cbf0b804ca6ce09d4efd6fe2b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Sat, 20 Sep 2025 13:44:39 -0300 Subject: [PATCH 105/114] add floating prj number output --- 4-projects/business_unit_1/nonproduction/README.md | 1 + 4-projects/business_unit_1/nonproduction/outputs.tf | 5 +++++ 4-projects/business_unit_1/production/README.md | 1 + 4-projects/business_unit_1/production/outputs.tf | 5 +++++ 4 files changed, 12 insertions(+) diff --git a/4-projects/business_unit_1/nonproduction/README.md b/4-projects/business_unit_1/nonproduction/README.md index aa1af1107..b07fab164 100644 --- a/4-projects/business_unit_1/nonproduction/README.md +++ b/4-projects/business_unit_1/nonproduction/README.md @@ -21,6 +21,7 @@ | bucket | The created storage bucket. | | default\_region | The default region for the project. | | floating\_project | Project sample floating project. | +| floating\_project\_number | Project number sample floating project. | | iap\_firewall\_tags | The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project. | | keyring | The name of the keyring. | | keys | List of created key names. | diff --git a/4-projects/business_unit_1/nonproduction/outputs.tf b/4-projects/business_unit_1/nonproduction/outputs.tf index eb85ba83e..3e517112e 100644 --- a/4-projects/business_unit_1/nonproduction/outputs.tf +++ b/4-projects/business_unit_1/nonproduction/outputs.tf @@ -19,6 +19,11 @@ output "floating_project" { value = module.env.floating_project } +output "floating_project_number" { + description = "Project number sample floating project." + value = module.env.floating_project_number +} + output "peering_project" { description = "Project sample peering project id." value = module.env.peering_project diff --git a/4-projects/business_unit_1/production/README.md b/4-projects/business_unit_1/production/README.md index 2df80510d..27eac9c1b 100644 --- a/4-projects/business_unit_1/production/README.md +++ b/4-projects/business_unit_1/production/README.md @@ -21,6 +21,7 @@ | bucket | The created storage bucket. | | default\_region | The default region for the project. | | floating\_project | Project sample floating project. | +| floating\_project\_number | Project number sample floating project. | | iap\_firewall\_tags | The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project. | | keyring | The name of the keyring. | | keys | List of created key names. | diff --git a/4-projects/business_unit_1/production/outputs.tf b/4-projects/business_unit_1/production/outputs.tf index a4bc488f1..926392711 100644 --- a/4-projects/business_unit_1/production/outputs.tf +++ b/4-projects/business_unit_1/production/outputs.tf @@ -19,6 +19,11 @@ output "floating_project" { value = module.env.floating_project } +output "floating_project_number" { + description = "Project number sample floating project." + value = module.env.floating_project_number +} + output "peering_project" { description = "Project sample peering project id." value = module.env.peering_project From 99b097e0618033336a1c91d1dae1479462dccea1 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 22 Sep 2025 14:08:24 -0300 Subject: [PATCH 106/114] add dot in OAuth retry messsage error --- test/integration/testutils/retry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/testutils/retry.go b/test/integration/testutils/retry.go index 9a768aec2..124154420 100755 --- a/test/integration/testutils/retry.go +++ b/test/integration/testutils/retry.go @@ -44,7 +44,7 @@ var ( ".*Error 400.*Service account.*does not exist.*": "Error setting IAM policy", // Error waiting for creating service network connection. This happens randomly for development, production and non-production environments - ".*Error code 16.*Error waiting for Create Service Networking Connection.*Expected OAuth 2 access token.*": "Request had invalid authentication credentials", + ".*Error code 16.*Error waiting for Create Service Networking Connection.*Expected OAuth 2 access token.*": "Request had invalid authentication credentials.", // Error 400: The eTag provided {} does not match the eTag of the current version of the Access Policy, which is {}. ".*Error 400: The eTag provided.*does not match the eTag of the current version of the Access Policy, which is.*": "Conflict during Access Policy configuration.", From 255a3ed2a316f5713887188d392e595171ef42f2 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 22 Sep 2025 16:24:32 -0300 Subject: [PATCH 107/114] add depends_on --- 0-bootstrap/cb.tf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/0-bootstrap/cb.tf b/0-bootstrap/cb.tf index 3a3dff7d9..bf276e9a5 100644 --- a/0-bootstrap/cb.tf +++ b/0-bootstrap/cb.tf @@ -178,6 +178,8 @@ module "tf_cloud_builder" { worker_pool_id = module.tf_private_pool.private_worker_pool_id bucket_name = "${var.bucket_prefix}-${module.tf_source.cloudbuild_project_id}-tf-cloudbuilder-build-logs" workflow_deletion_protection = var.workflow_deletion_protection + + depends_on = [module.tf_source] } module "bootstrap_csr_repo" { From 55e4f5b6beab6aace83de54b7a46283c6f4a9d10 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 22 Sep 2025 18:32:30 -0300 Subject: [PATCH 108/114] fix retry message error --- test/integration/testutils/retry.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/testutils/retry.go b/test/integration/testutils/retry.go index 124154420..ccac99c80 100755 --- a/test/integration/testutils/retry.go +++ b/test/integration/testutils/retry.go @@ -44,7 +44,7 @@ var ( ".*Error 400.*Service account.*does not exist.*": "Error setting IAM policy", // Error waiting for creating service network connection. This happens randomly for development, production and non-production environments - ".*Error code 16.*Error waiting for Create Service Networking Connection.*Expected OAuth 2 access token.*": "Request had invalid authentication credentials.", + ".*Error waiting for Create Service Networking Connection.*Error code 16.*Expected OAuth 2 access token.*": "Request had invalid authentication credentials.", // Error 400: The eTag provided {} does not match the eTag of the current version of the Access Policy, which is {}. ".*Error 400: The eTag provided.*does not match the eTag of the current version of the Access Policy, which is.*": "Conflict during Access Policy configuration.", From 0c201c77e4104e256827df4c1c6faf108affa5c3 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 22 Sep 2025 20:49:07 -0300 Subject: [PATCH 109/114] add deletion_protection variabel in folder resources 1-org, updt service control versions.tf module --- 1-org/envs/shared/folders.tf | 12 ++++++------ 1-org/modules/service_control/versions.tf | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/1-org/envs/shared/folders.tf b/1-org/envs/shared/folders.tf index 90c69454a..488ca6430 100644 --- a/1-org/envs/shared/folders.tf +++ b/1-org/envs/shared/folders.tf @@ -19,13 +19,13 @@ *****************************************/ resource "google_folder" "common" { - display_name = "${local.folder_prefix}-common" - parent = local.parent - # deletion_protection = var.folder_deletion_protection // uncommnet after updating "GoogleCloudPlatform/cloud-functions/google" to provider v6 + display_name = "${local.folder_prefix}-common" + parent = local.parent + deletion_protection = var.folder_deletion_protection // uncommnet after updating "GoogleCloudPlatform/cloud-functions/google" to provider v6 } resource "google_folder" "network" { - display_name = "${local.folder_prefix}-network" - parent = local.parent - # deletion_protection = var.folder_deletion_protection // uncommnet after updating "GoogleCloudPlatform/cloud-functions/google" to provider v6 + display_name = "${local.folder_prefix}-network" + parent = local.parent + deletion_protection = var.folder_deletion_protection // uncommnet after updating "GoogleCloudPlatform/cloud-functions/google" to provider v6 } diff --git a/1-org/modules/service_control/versions.tf b/1-org/modules/service_control/versions.tf index c7d484d8a..7193ed1bc 100644 --- a/1-org/modules/service_control/versions.tf +++ b/1-org/modules/service_control/versions.tf @@ -20,12 +20,12 @@ terraform { google = { // version 6.26.0 removed because of the bug https://github.com/hashicorp/terraform-provider-google/issues/21950 source = "hashicorp/google" - version = ">= 3.50, < 6.26.0" + version = ">= 3.50, != 6.26.0, != 6.27.0, < 7.0" } google-beta = { // version 6.26.0 removed because of the bug https://github.com/hashicorp/terraform-provider-google/issues/21950 source = "hashicorp/google-beta" - version = ">= 3.50, < 6.26.0" + version = ">= 3.50, != 6.26.0, != 6.27.0, < 7.0" } random = { source = "hashicorp/random" From 62f725fa88e70dba73f08b6c18dda4bb98339f2b Mon Sep 17 00:00:00 2001 From: mariamartins Date: Tue, 23 Sep 2025 15:46:11 -0300 Subject: [PATCH 110/114] add depends on for cloud build nat instance --- 0-bootstrap/modules/cb-private-pool/network.tf | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/0-bootstrap/modules/cb-private-pool/network.tf b/0-bootstrap/modules/cb-private-pool/network.tf index 92f615d77..f513ab74e 100644 --- a/0-bootstrap/modules/cb-private-pool/network.tf +++ b/0-bootstrap/modules/cb-private-pool/network.tf @@ -218,6 +218,8 @@ resource "google_compute_address" "cloud_build_nat" { name = "cloud-build-nat" network_tier = "PREMIUM" region = "us-central1" + + depends_on = [module.peered_network] } resource "google_compute_instance" "vm-proxy" { @@ -250,7 +252,10 @@ resource "google_compute_instance" "vm-proxy" { scopes = ["cloud-platform"] } - depends_on = [resource.google_compute_router_nat.cb-nat] + depends_on = [ + resource.google_compute_router_nat.cb-nat, + module.peered_network + ] } # This route will route packets to the NAT VM From 5295db9acbde9694761e61509464cb91e275be1a Mon Sep 17 00:00:00 2001 From: mariamartins Date: Mon, 29 Sep 2025 10:27:00 -0300 Subject: [PATCH 111/114] fix bootstrap module version --- 0-bootstrap/cb.tf | 6 +++--- 0-bootstrap/main.tf | 2 +- 4-projects/modules/infra_pipelines/main.tf | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/0-bootstrap/cb.tf b/0-bootstrap/cb.tf index bf276e9a5..9d007e76c 100644 --- a/0-bootstrap/cb.tf +++ b/0-bootstrap/cb.tf @@ -84,7 +84,7 @@ module "gcp_projects_state_bucket" { module "tf_source" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_source" - version = "~> 11.0.1" + version = "~> 11.0" org_id = var.org_id folder_id = google_folder.bootstrap.id @@ -164,7 +164,7 @@ module "tf_private_pool" { module "tf_cloud_builder" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_builder" - version = "~> 11.0.1" + version = "~> 11.0" project_id = module.tf_source.cloudbuild_project_id dockerfile_repo_uri = module.tf_source.csr_repos[local.cloudbuilder_repo].url @@ -218,7 +218,7 @@ module "build_terraform_image" { module "tf_workspace" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace" - version = "~> 11.0.1" + version = "~> 11.0" for_each = local.granular_sa project_id = module.tf_source.cloudbuild_project_id diff --git a/0-bootstrap/main.tf b/0-bootstrap/main.tf index c33e3e415..81d7e634f 100644 --- a/0-bootstrap/main.tf +++ b/0-bootstrap/main.tf @@ -45,7 +45,7 @@ resource "google_folder" "bootstrap" { module "seed_bootstrap" { source = "terraform-google-modules/bootstrap/google" - version = "~> 11.0.1" + version = "~> 11.0" org_id = var.org_id folder_id = google_folder.bootstrap.id diff --git a/4-projects/modules/infra_pipelines/main.tf b/4-projects/modules/infra_pipelines/main.tf index 27521165b..ab0da04ea 100644 --- a/4-projects/modules/infra_pipelines/main.tf +++ b/4-projects/modules/infra_pipelines/main.tf @@ -55,7 +55,7 @@ resource "google_storage_bucket" "cloudbuild_bucket" { module "tf_workspace" { source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace" - version = "~> 11.0.1" + version = "~> 11.0" for_each = toset(var.app_infra_repos) From 589b59035e19cd2638caa61848afbc99e7fa8bdf Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 2 Oct 2025 08:13:47 -0300 Subject: [PATCH 112/114] updt documentai.googleapis.com service --- test/integration/org/org_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go index dcbb3ca88..f565c90ea 100755 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -76,7 +76,7 @@ func TestOrg(t *testing.T) { "adsdatahub.googleapis.com", "aiplatform.googleapis.com", "alloydb.googleapis.com", - "alpha-documentai.googleapis.com", + "documentai.googleapis.com", "analyticshub.googleapis.com", "apigee.googleapis.com", "apigeeconnect.googleapis.com", From 4fa07fcc1b9a8f8ede9ea06a8f95036fedfd81e4 Mon Sep 17 00:00:00 2001 From: mariamartins Date: Thu, 2 Oct 2025 08:18:34 -0300 Subject: [PATCH 113/114] fix required directional policies keys and roles list --- 1-org/envs/shared/README.md | 1 + 1-org/envs/shared/remote.tf | 39 ++++ 1-org/envs/shared/service_control.tf | 270 ++++++++++++++++----------- 1-org/envs/shared/variables.tf | 9 + 4 files changed, 205 insertions(+), 114 deletions(-) diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 2480f64c6..5a5d3126e 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -18,6 +18,7 @@ | enable\_kms\_key\_usage\_tracking | Enable KMS centralized key usage tracking system. | `bool` | `true` | no | | enable\_scc\_resources\_in\_terraform | Create Security Command Center resources in Terraform. Security Command Center must be activated before the creation of the resources. See [Overview of activating Security Command Center](https://cloud.google.com/security-command-center/docs/activate-scc-overview) before enabling this feature. | `bool` | `false` | no | | enforce\_allowed\_worker\_pools | Whether to enforce the organization policy restriction on allowed worker pools for Cloud Build. | `bool` | `false` | no | +| envs | n/a | `map(bool)` |
{
"development": true,
"nonproduction": true,
"production": true
}
| no | | essential\_contacts\_domains\_to\_allow | The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes | | essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no | | folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | no | diff --git a/1-org/envs/shared/remote.tf b/1-org/envs/shared/remote.tf index f514676cd..3cbe09888 100644 --- a/1-org/envs/shared/remote.tf +++ b/1-org/envs/shared/remote.tf @@ -39,6 +39,23 @@ locals { seed_project_id = data.terraform_remote_state.bootstrap.outputs.seed_project_id seed_project_number = data.terraform_remote_state.bootstrap.outputs.seed_project_number parent_id = data.terraform_remote_state.bootstrap.outputs.parent_id + projects_gcs_bucket_tfstate = data.terraform_remote_state.bootstrap.outputs.projects_gcs_bucket_tfstate + peering_projects_numbers = compact([for s in data.terraform_remote_state.projects_env : try(s.outputs.peering_project_number, null)]) + shared_vpc_project_numbers = compact([for s in data.terraform_remote_state.projects_env : try(s.outputs.shared_vpc_project_number, null)]) + app_infra_project_id = try(data.terraform_remote_state.projects_app_infra[0].outputs.cloudbuild_project_id, null) + app_infra_project_number = try(data.terraform_remote_state.projects_app_infra[0].outputs.cloudbuild_project_number, null) + + app_infra_pipeline_identity = local.app_infra_project_number != null ? "serviceAccount:${local.app_infra_project_number}@cloudbuild.gserviceaccount.com" : null + app_infra_pipeline_source_projects = local.app_infra_project_number != null ? ["projects/${local.app_infra_project_number}"] : [] + app_infra_targets = distinct(concat( + [for n in local.shared_vpc_project_numbers : "projects/${n}"], + [for n in local.peering_projects_numbers : "projects/${n}"] + )) + app_infra_cicd_identity = ( + local.app_infra_project_id != null + ? "serviceAccount:sa-tf-cb-bu1-example-app@${local.app_infra_project_id}.iam.gserviceaccount.com" + : null + ) } data "terraform_remote_state" "bootstrap" { @@ -49,3 +66,25 @@ data "terraform_remote_state" "bootstrap" { prefix = "terraform/bootstrap/state" } } + +data "terraform_remote_state" "projects_env" { + backend = "gcs" + + for_each = (var.required_egress_rules_app_infra_dry_run && var.required_ingress_rules_app_infra_dry_run) || (var.required_egress_rules_app_infra && var.required_ingress_rules_app_infra) ? var.envs : {} + + config = { + bucket = local.projects_gcs_bucket_tfstate + prefix = "terraform/projects/business_unit_1/${each.key}" + } +} + +data "terraform_remote_state" "projects_app_infra" { + backend = "gcs" + + count = (var.required_egress_rules_app_infra_dry_run && var.required_ingress_rules_app_infra_dry_run) || (var.required_egress_rules_app_infra && var.required_ingress_rules_app_infra) ? 1 : 0 + + config = { + bucket = local.projects_gcs_bucket_tfstate + prefix = "terraform/projects/business_unit_1/shared" + } +} diff --git a/1-org/envs/shared/service_control.tf b/1-org/envs/shared/service_control.tf index c40cbe978..712a5c2d9 100644 --- a/1-org/envs/shared/service_control.tf +++ b/1-org/envs/shared/service_control.tf @@ -26,7 +26,6 @@ locals { "adsdatahub.googleapis.com", "aiplatform.googleapis.com", "alloydb.googleapis.com", - "alpha-documentai.googleapis.com", "analyticshub.googleapis.com", "apigee.googleapis.com", "apigeeconnect.googleapis.com", @@ -148,8 +147,9 @@ locals { restricted_services = length(var.custom_restricted_services) != 0 ? var.custom_restricted_services : local.supported_restricted_service restricted_services_dry_run = length(var.custom_restricted_services_dry_run) != 0 ? var.custom_restricted_services : local.supported_restricted_service - access_level_name = module.service_control.access_level_name - access_level_dry_run_name = module.service_control.access_level_name_dry_run + + access_level_name = module.service_control.access_level_name + access_level_dry_run_name = module.service_control.access_level_name_dry_run shared_vpc_projects_numbers = [ for v in values({ @@ -253,37 +253,50 @@ locals { projects_map_dry_run = zipmap( local.project_keys_dry_run, - [for p in local.projects : "${p}"] + [for p in local.projects_dry_run : "${p}"] ) - ingress_policies_keys_dry_run = var.required_ingress_rules_app_infra_dry_run ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys_dry_run) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys_dry_run) - egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) - ingress_policies_keys = var.required_ingress_rules_app_infra ? concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed", "cicd_to_app_infra", "cicd_to_seed_app_infra", "cicd_to_net_env"], var.ingress_policies_keys) : concat(["billing_sa_to_prj", "sinks_sa_to_logs", "service_cicd_to_seed", "cicd_to_seed"], var.ingress_policies_keys) - egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) - - ingress_policies_map_dry_run = var.required_ingress_rules_app_infra_dry_run ? zipmap( - local.ingress_policies_keys_dry_run, - [for r in concat(local.required_ingress_rules_dry_run, local.required_ingress_rules_app_infra_dry_run) : "${r}"] - ) : zipmap(local.ingress_policies_keys_dry_run, - [for r in local.required_ingress_rules_dry_run : "${r}"]) - - egress_policies_map_dry_run = var.required_egress_rules_app_infra_dry_run ? zipmap( - local.egress_policies_keys_dry_run, - [for r in concat(local.required_egress_rules_dry_run, local.required_egress_rules_app_infra_dry_run) : "${r}"] - ) : zipmap(local.egress_policies_keys_dry_run, - [for r in local.required_egress_rules_dry_run : "${r}"]) - - ingress_policies_map = var.required_ingress_rules_app_infra ? zipmap( - local.ingress_policies_keys, - [for r in concat(local.required_ingress_rules, local.required_ingress_rules_app_infra) : "${r}"] - ) : zipmap(local.ingress_policies_keys, - [for r in local.required_ingress_rules : "${r}"]) - - egress_policies_map = var.required_egress_rules_app_infra ? zipmap( - local.egress_policies_keys, - [for r in concat(local.required_egress_rules, local.required_egress_rules_app_infra) : "${r}"] - ) : zipmap(local.egress_policies_keys, - [for r in local.required_egress_rules : "${r}"]) + base_ingress_keys = [ + "billing_sa_to_prj", + "sinks_sa_to_logs", + "service_cicd_to_seed", + "cicd_to_seed", + ] + + app_infra_ingress_keys_dry_run = [ + "cicd_to_app_infra", + "cicd_to_seed_app_infra", + "cicd_to_net_env", + ] + + scc_ingress_key_dry_run = "cai_monitoring_to_scc" + + app_infra_ingress_keys = [ + "cicd_to_app_infra", + "cicd_to_seed_app_infra", + "cicd_to_net_env", + ] + + scc_ingress_key = "cai_monitoring_to_scc" + + ingress_policies_keys_dry_run = concat( + local.base_ingress_keys, + var.required_ingress_rules_app_infra_dry_run ? local.app_infra_ingress_keys_dry_run : [], + var.enable_scc_resources_in_terraform ? [local.scc_ingress_key_dry_run] : [], + var.ingress_policies_keys_dry_run + ) + + ingress_policies_keys = concat( + local.base_ingress_keys, + var.required_ingress_rules_app_infra ? local.app_infra_ingress_keys : [], + var.enable_scc_resources_in_terraform ? [local.scc_ingress_key] : [], + var.ingress_policies_keys + ) + + egress_policies_keys_dry_run = var.required_egress_rules_app_infra_dry_run ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys_dry_run) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys_dry_run) + egress_policies_keys = var.required_egress_rules_app_infra ? concat(["seed_to_cicd", "org_sa_to_scc", "app_infra_to_cicd"], var.egress_policies_keys) : concat(["seed_to_cicd", "org_sa_to_scc"], var.egress_policies_keys) + app_infra_targets_sorted = sort(local.app_infra_targets) + app_infra_to_resources = local.app_infra_project_number != null ? ["projects/${local.app_infra_project_number}"] : [] required_egress_rules_dry_run = [ { @@ -338,13 +351,9 @@ locals { { title = "ER app infra -> cicd" from = { - identities = [ - "serviceAccount:PRJ_APP_INFRA_PIPELINE_NUMBER@cloudbuild.gserviceaccount.com", - ] + identities = compact([local.app_infra_pipeline_identity]) sources = { - resources = [ - "projects/PRJ_APP_INFRA_PIPELINE_NUMBER" - ] + resources = local.app_infra_pipeline_source_projects } } to = { @@ -368,9 +377,7 @@ locals { "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", ] sources = { - access_levels = [ - "*" - ] + access_levels = ["*"] } } to = { @@ -392,9 +399,7 @@ locals { "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", ] sources = { - access_levels = [ - "*" - ] + access_levels = ["*"] } } to = { @@ -405,15 +410,12 @@ locals { "logging.googleapis.com" = { methods = ["*"] } - "pubsub.googleapis.com" = { methods = ["*"] } - "storage.googleapis.com" = { methods = ["*"] } - } } }, @@ -468,13 +470,41 @@ locals { }, ] - required_ingress_rules_app_infra_dry_run = [ + required_ingress_rule_scc_dry_run = [ { - title = "IR cicd -> app infra" + title = "CAI -> SCC" from = { identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", + try("serviceAccount:${google_service_account.cai_monitoring_builder[0].email}", null) ] + sources = { + access_levels = ["*"] + } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + "artifactregistry.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { + methods = ["*"] + } + } + } + }, + ] + + required_ingress_rules_app_infra_dry_run = [ + { + title = "IR cicd -> app infra" + from = { + identities = compact([local.app_infra_cicd_identity]) sources = { resources = [ "projects/${local.cloudbuild_project_number}" @@ -482,9 +512,7 @@ locals { } } to = { - resources = [ - "projects/PRJ_BU1_APP_INFRA_NUMBER" - ] + resources = local.app_infra_to_resources operations = { "storage.googleapis.com" = { methods = ["*"] @@ -501,9 +529,7 @@ locals { { title = "IR app infra -> seed" from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", - ] + identities = compact([local.app_infra_cicd_identity]) sources = { resources = [ "projects/${local.cloudbuild_project_number}" @@ -524,9 +550,7 @@ locals { { title = "IR app infra -> prjs" from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", - ] + identities = compact([local.app_infra_cicd_identity]) sources = { resources = [ "projects/${local.cloudbuild_project_number}" @@ -534,14 +558,7 @@ locals { } } to = { - resources = [ - "projects/PRJS_DEV_SAMPLE_SVPC_NUMBER", - "projects/PRJS_DEV_SAMPLE_PEERING_NUMBER", - "projects/PRJS_PROD_SAMPLE_SVPC_NUMBER", - "projects/PRJS_PROD_SAMPLE_PEERING_NUMBER", - "projects/PRJS_NONPROD_SAMPLE_SVPC_NUMBER", - "projects/PRJS_NONPROD_SAMPLE_PEERING_NUMBER" - ] + resources = local.app_infra_targets_sorted operations = { "iam.googleapis.com" = { methods = ["*"] @@ -562,9 +579,7 @@ locals { "serviceAccount:billing-export-bigquery@system.gserviceaccount.com", ] sources = { - access_levels = [ - "*" - ] + access_levels = ["*"] } } to = { @@ -586,9 +601,7 @@ locals { "serviceAccount:service-b-${local.billing_account}@gcp-sa-logging.iam.gserviceaccount.com", ] sources = { - access_levels = [ - "*" - ] + access_levels = ["*"] } } to = { @@ -599,15 +612,12 @@ locals { "logging.googleapis.com" = { methods = ["*"] } - "pubsub.googleapis.com" = { methods = ["*"] } - "storage.googleapis.com" = { methods = ["*"] } - } } }, @@ -641,7 +651,7 @@ locals { title = "IR cicd -> seed" from = { identities = [ - "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com" ] sources = { resources = [ @@ -654,7 +664,33 @@ locals { "projects/${local.seed_project_number}" ] operations = { - "cloudbuild.googleapis.com" = { + "cloudbuild.googleapis.com" = { methods = ["*"] } + } + } + }, + ] + + required_ingress_rule_scc = [ + { + title = "CAI -> SCC" + from = { + identities = [ + try("serviceAccount:${google_service_account.cai_monitoring_builder[0].email}", null) + ] + sources = { access_levels = ["*"] } + } + to = { + resources = [ + "projects/${module.scc_notifications.project_number}" + ] + operations = { + "logging.googleapis.com" = { + methods = ["*"] + } + "artifactregistry.googleapis.com" = { + methods = ["*"] + } + "storage.googleapis.com" = { methods = ["*"] } } @@ -666,9 +702,7 @@ locals { { title = "IR cicd -> app infra" from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", - ] + identities = compact([local.app_infra_cicd_identity]) sources = { resources = [ "projects/${local.cloudbuild_project_number}" @@ -676,9 +710,7 @@ locals { } } to = { - resources = [ - "projects/PRJ_BU1_APP_INFRA_NUMBER" - ] + resources = local.app_infra_to_resources operations = { "storage.googleapis.com" = { methods = ["*"] @@ -695,9 +727,7 @@ locals { { title = "IR app infra -> seed" from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", - ] + identities = compact([local.app_infra_cicd_identity]) sources = { resources = [ "projects/${local.cloudbuild_project_number}" @@ -718,9 +748,7 @@ locals { { title = "IR app infra -> prjs" from = { - identities = [ - "serviceAccount:sa-tf-cb-bu1-example-app@PRJ_APP_INFRA_ID.iam.gserviceaccount.com", - ] + identities = compact([local.app_infra_cicd_identity]) sources = { resources = [ "projects/${local.cloudbuild_project_number}" @@ -728,14 +756,7 @@ locals { } } to = { - resources = [ - "projects/PRJS_DEV_SAMPLE_SVPC_NUMBER", - "projects/PRJS_DEV_SAMPLE_PEERING_NUMBER", - "projects/PRJS_PROD_SAMPLE_SVPC_NUMBER", - "projects/PRJS_PROD_SAMPLE_PEERING_NUMBER", - "projects/PRJS_NONPROD_SAMPLE_SVPC_NUMBER", - "projects/PRJS_NONPROD_SAMPLE_PEERING_NUMBER" - ] + resources = local.app_infra_targets_sorted operations = { "iam.googleapis.com" = { methods = ["*"] @@ -753,7 +774,7 @@ locals { title = "ER seed -> cicd" from = { identities = [ - "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com", + "serviceAccount:${local.cloudbuild_project_number}@cloudbuild.gserviceaccount.com" ] sources = { resources = [ @@ -776,7 +797,7 @@ locals { title = "ER cicd -> scc" from = { identities = [ - "serviceAccount:${local.organization_service_account}", + "serviceAccount:${local.organization_service_account}" ] sources = { resources = [ @@ -801,13 +822,9 @@ locals { { title = "ER app infra -> cicd" from = { - identities = [ - "serviceAccount:PRJ_APP_INFRA_PIPELINE_NUMBER@cloudbuild.gserviceaccount.com", - ] + identities = compact([local.app_infra_pipeline_identity]) sources = { - resources = [ - "projects/PRJ_APP_INFRA_PIPELINE_NUMBER" - ] + resources = local.app_infra_pipeline_source_projects } } to = { @@ -822,6 +839,20 @@ locals { } }, ] + + required_ingress_rules_list_dry_run = concat( + local.required_ingress_rules_dry_run, + var.required_ingress_rules_app_infra_dry_run ? local.required_ingress_rules_app_infra_dry_run : [], + var.enable_scc_resources_in_terraform ? local.required_ingress_rule_scc_dry_run : [], + var.ingress_policies_dry_run + ) + + required_ingress_rules_list = concat( + local.required_ingress_rules, + var.required_ingress_rules_app_infra ? local.required_ingress_rules_app_infra : [], + var.enable_scc_resources_in_terraform ? local.required_ingress_rule_scc : [], + var.ingress_policies + ) } module "service_control" { @@ -836,24 +867,35 @@ module "service_control" { "serviceAccount:${local.organization_service_account}", "serviceAccount:${local.environment_service_account}", ], var.perimeter_additional_members)) - resources = concat(values(local.projects_map), var.resources) - resource_keys = local.project_keys members_dry_run = distinct(concat([ "serviceAccount:${local.networks_service_account}", "serviceAccount:${local.projects_service_account}", "serviceAccount:${local.organization_service_account}", "serviceAccount:${local.environment_service_account}", ], var.perimeter_additional_members)) - resources_dry_run = concat(values(local.projects_map_dry_run), var.resources_dry_run) + resources = [for k in local.project_keys : local.projects_map[k]] + resource_keys = local.project_keys + resources_dry_run = [for k in local.project_keys_dry_run : local.projects_map_dry_run[k]] resource_keys_dry_run = local.project_keys_dry_run ingress_policies_keys_dry_run = local.ingress_policies_keys_dry_run - egress_policies_keys_dry_run = local.egress_policies_keys_dry_run ingress_policies_keys = local.ingress_policies_keys + egress_policies_keys_dry_run = local.egress_policies_keys_dry_run egress_policies_keys = local.egress_policies_keys - ingress_policies = var.required_ingress_rules_app_infra ? distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, local.required_ingress_rules_app_infra, var.ingress_policies)) : distinct(concat(values(local.ingress_policies_map), local.required_ingress_rules, var.ingress_policies)) - ingress_policies_dry_run = var.required_ingress_rules_app_infra_dry_run ? distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules_dry_run, local.required_ingress_rules_app_infra_dry_run, var.ingress_policies_dry_run)) : distinct(concat(values(local.ingress_policies_map_dry_run), local.required_ingress_rules_dry_run, var.ingress_policies_dry_run)) - egress_policies = var.required_egress_rules_app_infra ? distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules, local.required_egress_rules_app_infra)) : distinct(concat(values(local.egress_policies_map), var.egress_policies, local.required_egress_rules)) - egress_policies_dry_run = var.required_egress_rules_app_infra_dry_run ? distinct(concat(values(local.egress_policies_map_dry_run), var.egress_policies_dry_run, local.required_egress_rules_dry_run, local.required_egress_rules_app_infra_dry_run)) : distinct(concat(values(local.egress_policies_map_dry_run), local.required_egress_rules_dry_run, var.egress_policies_dry_run)) + + ingress_policies_dry_run = local.required_ingress_rules_list_dry_run + ingress_policies = local.required_ingress_rules_list + + egress_policies_dry_run = concat( + local.required_egress_rules_dry_run, + var.required_egress_rules_app_infra_dry_run ? local.required_egress_rules_app_infra_dry_run : [], + var.egress_policies_dry_run + ) + + egress_policies = concat( + local.required_egress_rules, + var.required_egress_rules_app_infra ? local.required_egress_rules_app_infra : [], + var.egress_policies + ) depends_on = [ time_sleep.wait_projects diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index f30e939ac..9697f9c09 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -387,3 +387,12 @@ variable "required_ingress_rules_app_infra_dry_run" { type = bool default = false } + +variable "envs" { + type = map(bool) + default = { + development = true + nonproduction = true + production = true + } +} From f233219237f0167112c14d4ed54b51360573800e Mon Sep 17 00:00:00 2001 From: Maria Martins Date: Thu, 16 Oct 2025 12:09:33 -0300 Subject: [PATCH 114/114] update 4-projects README instruction and bump cloud function module version --- 1-org/envs/shared/folders.tf | 4 +- 1-org/modules/cai-monitoring/main.tf | 8 ++- 4-projects/README.md | 76 ---------------------------- 3 files changed, 5 insertions(+), 83 deletions(-) diff --git a/1-org/envs/shared/folders.tf b/1-org/envs/shared/folders.tf index 488ca6430..484589573 100644 --- a/1-org/envs/shared/folders.tf +++ b/1-org/envs/shared/folders.tf @@ -21,11 +21,11 @@ resource "google_folder" "common" { display_name = "${local.folder_prefix}-common" parent = local.parent - deletion_protection = var.folder_deletion_protection // uncommnet after updating "GoogleCloudPlatform/cloud-functions/google" to provider v6 + deletion_protection = var.folder_deletion_protection } resource "google_folder" "network" { display_name = "${local.folder_prefix}-network" parent = local.parent - deletion_protection = var.folder_deletion_protection // uncommnet after updating "GoogleCloudPlatform/cloud-functions/google" to provider v6 + deletion_protection = var.folder_deletion_protection } diff --git a/1-org/modules/cai-monitoring/main.tf b/1-org/modules/cai-monitoring/main.tf index f089caec5..ecbfd157b 100644 --- a/1-org/modules/cai-monitoring/main.tf +++ b/1-org/modules/cai-monitoring/main.tf @@ -140,12 +140,10 @@ resource "google_scc_v2_organization_source" "cai_monitoring" { } // Cloud Function -//Using branch 'release-please--branches--main' due to Registry v0.6 incompability with Google Provider. -//TODO: update to the latest Registry version when released. + module "cloud_function" { - source = "git::https://github.com/GoogleCloudPlatform/terraform-google-cloud-functions.git?ref=release-please--branches--main" - # source = "GoogleCloudPlatform/cloud-functions/google" - # version = "~> 0.6" + source = "GoogleCloudPlatform/cloud-functions/google" + version = "~> 0.7" function_name = "caiMonitoring" description = "Check on the Organization for members (users, groups and service accounts) that contains the IAM roles listed." diff --git a/4-projects/README.md b/4-projects/README.md index b9af1b3db..e9db128c8 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -241,44 +241,6 @@ grep -rl 10.3.64.0 business_unit_2/ | xargs sed -i 's/10.3.64.0/10.4.64.0/g' sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" /envs/shared/service_control.tf ``` -1. Use `terraform output` to get the Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project. -1. Use `gsutil cat` to get the project numbers of the SVPC and Peering projects in each environment (production, nonproduction, and development) for configuring the directional app infra policies. - - ```bash - export projects_gcs_bucket_tfstate=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw projects_gcs_bucket_tfstate) - echo "projects_gcs_bucket_tfstate = ${projects_gcs_bucket_tfstate}" - - export peering_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ - | jq -r '.outputs.peering_project_number.value') - echo "peering_project_number_dev = ${peering_project_number_dev}" - sed -i'' -e "s/PRJS_DEV_SAMPLE_PEERING_NUMBER/${peering_project_number_dev}/" envs/shared/service_control.tf - - export peering_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ - | jq -r '.outputs.peering_project_number.value') - echo "peering_project_number_prod = ${peering_project_number_prod}" - sed -i'' -e "s/PRJS_PROD_SAMPLE_PEERING_NUMBER/${peering_project_number_prod}/" envs/shared/service_control.tf - - export peering_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ - | jq -r '.outputs.peering_project_number.value') - echo "peering_project_number_nonprod = ${peering_project_number_nonprod}" - sed -i'' -e "s/PRJS_NONPROD_SAMPLE_PEERING_NUMBER/${peering_project_number_nonprod}/" envs/shared/service_control.tf - - export shared_vpc_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ - | jq -r '.outputs.shared_vpc_project_number.value') - echo "shared_vpc_project_number_dev = ${shared_vpc_project_number_dev}" - sed -i'' -e "s/PRJS_DEV_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_dev}/" /envs/shared/service_control.tf - - export shared_vpc_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ - | jq -r '.outputs.shared_vpc_project_number.value') - echo "shared_vpc_project_number_prod = ${shared_vpc_project_number_prod}" - sed -i'' -e "s/PRJS_PROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_prod}/" /envs/shared/service_control.tf - - export shared_vpc_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ - | jq -r '.outputs.shared_vpc_project_number.value') - echo "shared_vpc_project_number_nonprod = ${shared_vpc_project_number_nonprod}" - sed -i'' -e "s/PRJS_NONPROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_nonprod}/" /envs/shared/service_control.tf - ``` - 1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` and `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. ```bash @@ -518,44 +480,6 @@ If you received any errors or made any changes to the Terraform config or any `. sed -i'' -e "s/PRJ_APP_INFRA_ID/${cloudbuild_project_id}/" /envs/shared/service_control.tf ``` -1. Use `terraform output` to get the Bucket used for storing terraform state for stage 4-projects foundations pipelines in seed project. -1. Use `gsutil cat` to get the project numbers of the SVPC and Peering projects in each environment (production, nonproduction, and development) for configuring the directional app infra policies. - - ```bash - export projects_gcs_bucket_tfstate=$(terraform -chdir="../terraform-example-foundation/0-bootstrap/" output -raw projects_gcs_bucket_tfstate) - echo "projects_gcs_bucket_tfstate = ${projects_gcs_bucket_tfstate}" - - export peering_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ - | jq -r '.outputs.peering_project_number.value') - echo "peering_project_number_dev = ${peering_project_number_dev}" - sed -i'' -e "s/PRJS_DEV_SAMPLE_PEERING_NUMBER/${peering_project_number_dev}/" envs/shared/service_control.tf - - export peering_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ - | jq -r '.outputs.peering_project_number.value') - echo "peering_project_number_prod = ${peering_project_number_prod}" - sed -i'' -e "s/PRJS_PROD_SAMPLE_PEERING_NUMBER/${peering_project_number_prod}/" envs/shared/service_control.tf - - export peering_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ - | jq -r '.outputs.peering_project_number.value') - echo "peering_project_number_nonprod = ${peering_project_number_nonprod}" - sed -i'' -e "s/PRJS_NONPROD_SAMPLE_PEERING_NUMBER/${peering_project_number_nonprod}/" envs/shared/service_control.tf - - export shared_vpc_project_number_dev=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/development/default.tfstate \ - | jq -r '.outputs.shared_vpc_project_number.value') - echo "shared_vpc_project_number_dev = ${shared_vpc_project_number_dev}" - sed -i'' -e "s/PRJS_DEV_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_dev}/" /envs/shared/service_control.tf - - export shared_vpc_project_number_prod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/production/default.tfstate \ - | jq -r '.outputs.shared_vpc_project_number.value') - echo "shared_vpc_project_number_prod = ${shared_vpc_project_number_prod}" - sed -i'' -e "s/PRJS_PROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_prod}/" /envs/shared/service_control.tf - - export shared_vpc_project_number_nonprod=$(gsutil cat gs://${projects_gcs_bucket_tfstate}/terraform/projects/business_unit_1/nonproduction/default.tfstate \ - | jq -r '.outputs.shared_vpc_project_number.value') - echo "shared_vpc_project_number_nonprod = ${shared_vpc_project_number_nonprod}" - sed -i'' -e "s/PRJS_NONPROD_SAMPLE_SVPC_NUMBER/${shared_vpc_project_number_nonprod}/" /envs/shared/service_control.tf - ``` - 1. If you are deploying with VPC Service Controls in dry run mode, update the `required_egress_rule_app_infra_dry_run` and `required_ingress_rule_app_infra_dry_run` variables to true, if you are deploying with VPC Service Controls in enforced mode, update the `required_egress_rule_app_infra` and `required_ingress_rule_app_infra` variables to true in [service_control.tf](gcp-org/envs/shared/service_control.tf) file. ```bash