From a761a99f8f4ad93b7fec37887bc34848015eb091 Mon Sep 17 00:00:00 2001 From: Daniel Andrade Date: Wed, 31 Aug 2022 21:53:57 -0300 Subject: [PATCH] feat!: use remote state to read data from previous steps (#782) * add output for remote state information * use remote state in step 1-org * fix integration test * use remote state date in step 5 * fix disable script * add force destroy on bootstrap * update outputs for step 1-org * update tests * add remote state to step 2-envs * move backend initialization to the end of apply phase * user remote state in step 4-projects * add remote state to 3-networks-dual-svpc * add remote state to 3-networks-hub-and-spoke * update test to use remote state in step 3-networks * fix bootstrap apply stage in integration test * fix soft link cyclo * update script to disable tf files * fix step 5-app-infra test * remove extra vars from test initialization * remove terraform service account from the var in step 4 integration test * remove project service account from test vars * split projects test into test for shared and test for envs * fix READMEs and tfvars files * restore 5-app-infra * remove remote_state.tf file * fix null provider version * restore gcloud beta terraform vet info * remove interpolation from backend_bucket usage * organize remote state values * add explanation of usage of remote state output values Co-authored-by: Bharath KKB --- 0-bootstrap/README.md | 1 + 0-bootstrap/modules/parent-iam-member/main.tf | 17 ++- .../modules/parent-iam-member/variables.tf | 6 +- 0-bootstrap/outputs.tf | 14 +++ 0-bootstrap/sa.tf | 25 ++++ 1-org/envs/shared/README.md | 8 +- 1-org/envs/shared/folders.tf | 6 +- 1-org/envs/shared/iam.tf | 48 +++---- 1-org/envs/shared/log_sinks.tf | 6 +- 1-org/envs/shared/main.tf | 38 ++++++ 1-org/envs/shared/org_policy.tf | 8 +- 1-org/envs/shared/outputs.tf | 7 +- 1-org/envs/shared/projects.tf | 48 +++---- 1-org/envs/shared/scc_notification.tf | 2 +- 1-org/envs/shared/terraform.example.tfvars | 14 +-- 1-org/envs/shared/variables.tf | 51 ++------ 2-environments/envs/development/README.md | 7 +- 2-environments/envs/development/main.tf | 11 +- 2-environments/envs/development/outputs.tf | 5 + 2-environments/envs/development/variables.tf | 27 +--- 2-environments/envs/non-production/README.md | 7 +- 2-environments/envs/non-production/main.tf | 11 +- 2-environments/envs/non-production/outputs.tf | 5 + .../envs/non-production/variables.tf | 27 +--- 2-environments/envs/production/README.md | 7 +- 2-environments/envs/production/main.tf | 11 +- 2-environments/envs/production/outputs.tf | 5 + 2-environments/envs/production/variables.tf | 27 +--- 2-environments/modules/env_baseline/README.md | 7 +- .../modules/env_baseline/folders.tf | 11 +- 2-environments/modules/env_baseline/main.tf | 17 ++- .../modules/env_baseline/monitoring.tf | 6 +- .../modules/env_baseline/networking.tf | 12 +- .../modules/env_baseline/outputs.tf | 5 + .../modules/env_baseline/secrets.tf | 6 +- .../modules/env_baseline/variables.tf | 26 +--- 2-environments/terraform.example.tfvars | 7 +- .../common.auto.example.tfvars | 7 +- .../envs/development/README.md | 5 +- 3-networks-dual-svpc/envs/development/main.tf | 3 +- .../envs/development/outputs.tf | 5 + .../envs/development/variables.tf | 16 +-- .../envs/non-production/README.md | 5 +- .../envs/non-production/main.tf | 3 +- .../envs/non-production/outputs.tf | 5 + .../envs/non-production/variables.tf | 17 +-- .../envs/production/README.md | 5 +- 3-networks-dual-svpc/envs/production/main.tf | 3 +- .../envs/production/outputs.tf | 5 + .../envs/production/variables.tf | 16 +-- 3-networks-dual-svpc/envs/shared/README.md | 4 +- 3-networks-dual-svpc/envs/shared/dns-hub.tf | 33 ----- .../envs/shared/hierarchical_firewall.tf | 12 +- .../envs/shared/interconnect.tf.example | 5 +- 3-networks-dual-svpc/envs/shared/main.tf | 66 ++++++++-- .../shared/partner_interconnect.tf.example | 28 ++--- 3-networks-dual-svpc/envs/shared/variables.tf | 16 +-- .../modules/base_env/README.md | 4 +- .../modules/base_env/interconnect.tf.example | 10 +- 3-networks-dual-svpc/modules/base_env/main.tf | 69 ++++++---- .../base_env/partner_interconnect.tf.example | 24 ++-- .../modules/base_env/variables.tf | 22 +--- .../modules/base_env/vpn.tf.example | 45 +++---- .../modules/base_shared_vpc/README.md | 1 + .../modules/base_shared_vpc/dns.tf | 27 +--- .../modules/base_shared_vpc/variables.tf | 5 + .../modules/dedicated_interconnect/README.md | 3 +- .../modules/dedicated_interconnect/main.tf | 27 ++-- .../dedicated_interconnect/variables.tf | 10 +- .../modules/partner_interconnect/README.md | 4 +- .../modules/partner_interconnect/main.tf | 31 ++--- .../modules/partner_interconnect/variables.tf | 16 +-- .../modules/restricted_shared_vpc/README.md | 1 + .../modules/restricted_shared_vpc/dns.tf | 27 +--- .../restricted_shared_vpc/variables.tf | 5 + 3-networks-dual-svpc/modules/vpn-ha/README.md | 3 +- 3-networks-dual-svpc/modules/vpn-ha/main.tf | 17 +-- .../modules/vpn-ha/variables.tf | 15 +-- .../common.auto.example.tfvars | 6 +- .../envs/development/README.md | 5 +- .../envs/development/main.tf | 4 +- .../envs/development/outputs.tf | 5 + .../envs/development/variables.tf | 16 +-- .../envs/non-production/README.md | 5 +- .../envs/non-production/main.tf | 3 +- .../envs/non-production/outputs.tf | 5 + .../envs/non-production/variables.tf | 16 +-- .../envs/production/README.md | 5 +- .../envs/production/main.tf | 3 +- .../envs/production/outputs.tf | 5 + .../envs/production/variables.tf | 16 +-- .../envs/shared/README.md | 4 +- .../envs/shared/dns-hub.tf | 33 ----- .../envs/shared/hierarchical_firewall.tf | 12 +- .../envs/shared/interconnect.tf.example | 5 +- 3-networks-hub-and-spoke/envs/shared/main.tf | 74 +++++++++-- .../envs/shared/net-hubs.tf | 29 +---- .../shared/partner_interconnect.tf.example | 28 ++--- .../envs/shared/variables.tf | 16 +-- .../modules/base_env/README.md | 4 +- .../modules/base_env/interconnect.tf.example | 9 +- .../modules/base_env/main.tf | 117 ++++++++++------- .../base_env/partner_interconnect.tf.example | 24 ++-- .../modules/base_env/variables.tf | 22 +--- .../modules/base_env/vpn.tf.example | 45 +++---- .../modules/base_shared_vpc/README.md | 4 +- .../modules/base_shared_vpc/dns.tf | 27 +--- .../modules/base_shared_vpc/main.tf | 20 +-- .../modules/base_shared_vpc/variables.tf | 23 ++-- .../modules/dedicated_interconnect/README.md | 4 +- .../modules/dedicated_interconnect/main.tf | 27 ++-- .../dedicated_interconnect/variables.tf | 16 +-- .../modules/partner_interconnect/README.md | 5 +- .../modules/partner_interconnect/main.tf | 30 ++--- .../modules/partner_interconnect/variables.tf | 22 +--- .../modules/restricted_shared_vpc/README.md | 5 +- .../modules/restricted_shared_vpc/dns.tf | 27 +--- .../modules/restricted_shared_vpc/main.tf | 20 +-- .../restricted_shared_vpc/service_control.tf | 7 +- .../restricted_shared_vpc/variables.tf | 29 +++-- .../modules/vpn-ha/README.md | 5 +- .../modules/vpn-ha/main.tf | 17 +-- .../modules/vpn-ha/variables.tf | 27 +--- 4-projects/README.md | 46 +------ 4-projects/access_context.auto.example.tfvars | 17 --- .../business_unit_1.auto.example.tfvars | 17 --- .../business_unit_1/development/README.md | 12 +- .../development/access_context.auto.tfvars | 1 - .../development/business_unit_1.auto.tfvars | 1 - .../business_unit_1/development/main.tf | 21 ++-- .../business_unit_1/development/outputs.tf | 4 +- .../business_unit_1/development/variables.tf | 48 ++----- .../business_unit_1/non-production/README.md | 12 +- .../non-production/access_context.auto.tfvars | 1 - .../business_unit_1.auto.tfvars | 1 - .../business_unit_1/non-production/main.tf | 21 ++-- .../business_unit_1/non-production/outputs.tf | 4 +- .../non-production/variables.tf | 48 ++----- .../business_unit_1/production/README.md | 12 +- .../production/access_context.auto.tfvars | 1 - .../production/business_unit_1.auto.tfvars | 1 - 4-projects/business_unit_1/production/main.tf | 21 ++-- .../business_unit_1/production/outputs.tf | 4 +- .../business_unit_1/production/variables.tf | 48 ++----- 4-projects/business_unit_1/shared/README.md | 6 +- .../shared/example_infra_pipeline.tf | 12 +- 4-projects/business_unit_1/shared/folder.tf | 20 --- 4-projects/business_unit_1/shared/main.tf | 44 +++++++ .../business_unit_1/shared/variables.tf | 27 +--- .../business_unit_2.auto.example.tfvars | 17 --- .../business_unit_2/development/README.md | 12 +- .../development/access_context.auto.tfvars | 1 - .../development/business_unit_2.auto.tfvars | 1 - .../business_unit_2/development/main.tf | 21 ++-- .../business_unit_2/development/outputs.tf | 4 +- .../business_unit_2/development/variables.tf | 48 ++----- .../business_unit_2/non-production/README.md | 12 +- .../non-production/access_context.auto.tfvars | 1 - .../business_unit_2.auto.tfvars | 1 - .../business_unit_2/non-production/main.tf | 21 ++-- .../business_unit_2/non-production/outputs.tf | 4 +- .../non-production/variables.tf | 48 ++----- .../business_unit_2/production/README.md | 12 +- .../production/access_context.auto.tfvars | 1 - .../production/business_unit_2.auto.tfvars | 1 - 4-projects/business_unit_2/production/main.tf | 21 ++-- .../business_unit_2/production/outputs.tf | 4 +- .../business_unit_2/production/variables.tf | 48 ++----- 4-projects/business_unit_2/shared/README.md | 6 +- .../shared/example_infra_pipeline.tf | 12 +- 4-projects/business_unit_2/shared/folder.tf | 20 --- 4-projects/business_unit_2/shared/main.tf | 44 +++++++ .../business_unit_2/shared/variables.tf | 27 +--- 4-projects/common.auto.example.tfvars | 8 +- 4-projects/development.auto.example.tfvars | 5 +- 4-projects/modules/base_env/README.md | 12 +- .../example_base_shared_vpc_project.tf | 30 ++--- .../base_env/example_floating_project.tf | 11 +- .../base_env/example_peering_project.tf | 25 ++-- .../example_restricted_shared_vpc_project.tf | 27 ++-- .../modules/base_env/example_storage_cmek.tf | 11 +- 4-projects/modules/base_env/folder.tf | 21 ---- 4-projects/modules/base_env/main.tf | 70 +++++++++++ 4-projects/modules/base_env/outputs.tf | 10 ++ 4-projects/modules/base_env/variables.tf | 54 +------- 4-projects/modules/single_project/README.md | 2 + 4-projects/modules/single_project/data.tf | 26 ---- 4-projects/modules/single_project/main.tf | 4 +- .../modules/single_project/variables.tf | 12 ++ 4-projects/non-production.auto.example.tfvars | 5 +- 4-projects/production.auto.example.tfvars | 5 +- build/int.cloudbuild.yaml | 20 ++- test/disable_tf_files.sh | 73 ++--------- test/integration/bootstrap/bootstrap_test.go | 61 ++++++++- test/integration/envs/envs_test.go | 19 ++- test/integration/go.mod | 2 +- test/integration/go.sum | 4 +- test/integration/networks/networks_test.go | 7 ++ test/integration/org/org_test.go | 22 +++- .../projects-shared/projects_shared_test.go | 100 +++++++++++++++ test/integration/projects/projects_test.go | 118 ++++-------------- test/integration/shared/shared_test.go | 7 ++ test/setup/outputs.tf | 6 +- 203 files changed, 1474 insertions(+), 2142 deletions(-) create mode 100644 1-org/envs/shared/main.tf delete mode 100644 4-projects/access_context.auto.example.tfvars delete mode 100644 4-projects/business_unit_1.auto.example.tfvars delete mode 120000 4-projects/business_unit_1/development/access_context.auto.tfvars delete mode 120000 4-projects/business_unit_1/development/business_unit_1.auto.tfvars delete mode 120000 4-projects/business_unit_1/non-production/access_context.auto.tfvars delete mode 120000 4-projects/business_unit_1/non-production/business_unit_1.auto.tfvars delete mode 120000 4-projects/business_unit_1/production/access_context.auto.tfvars delete mode 120000 4-projects/business_unit_1/production/business_unit_1.auto.tfvars delete mode 100644 4-projects/business_unit_1/shared/folder.tf create mode 100644 4-projects/business_unit_1/shared/main.tf delete mode 100644 4-projects/business_unit_2.auto.example.tfvars delete mode 120000 4-projects/business_unit_2/development/access_context.auto.tfvars delete mode 120000 4-projects/business_unit_2/development/business_unit_2.auto.tfvars delete mode 120000 4-projects/business_unit_2/non-production/access_context.auto.tfvars delete mode 120000 4-projects/business_unit_2/non-production/business_unit_2.auto.tfvars delete mode 120000 4-projects/business_unit_2/production/access_context.auto.tfvars delete mode 120000 4-projects/business_unit_2/production/business_unit_2.auto.tfvars delete mode 100644 4-projects/business_unit_2/shared/folder.tf create mode 100644 4-projects/business_unit_2/shared/main.tf delete mode 100644 4-projects/modules/base_env/folder.tf create mode 100644 4-projects/modules/base_env/main.tf delete mode 100644 4-projects/modules/single_project/data.tf create mode 100644 test/integration/projects-shared/projects_shared_test.go diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md index 20f7519ce..95b4ec6a4 100644 --- a/0-bootstrap/README.md +++ b/0-bootstrap/README.md @@ -194,6 +194,7 @@ the following steps: | Name | Description | |------|-------------| | cloudbuild\_project\_id | Project where CloudBuild configuration and terraform container image will reside. | +| 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 | | gcs\_bucket\_cloudbuild\_artifacts | Bucket used to store Cloud/Build artifacts in CloudBuild project. | diff --git a/0-bootstrap/modules/parent-iam-member/main.tf b/0-bootstrap/modules/parent-iam-member/main.tf index ab94eaefc..164f20b84 100644 --- a/0-bootstrap/modules/parent-iam-member/main.tf +++ b/0-bootstrap/modules/parent-iam-member/main.tf @@ -15,12 +15,13 @@ */ locals { - org_id = var.parent_type == "organization" ? var.parent_id : "" - folder_id = var.parent_type == "folder" ? var.parent_id : "" + org_id = var.parent_type == "organization" ? var.parent_id : "" + folder_id = var.parent_type == "folder" ? var.parent_id : "" + project_id = var.parent_type == "project" ? var.parent_id : "" } resource "google_organization_iam_member" "org_parent_iam" { - for_each = toset(local.org_id != "" ? var.roles : []) + for_each = toset(var.parent_type == "organization" ? var.roles : []) org_id = local.org_id role = each.key @@ -28,9 +29,17 @@ resource "google_organization_iam_member" "org_parent_iam" { } resource "google_folder_iam_member" "folder_parent_iam" { - for_each = toset(local.folder_id != "" ? var.roles : []) + for_each = toset(var.parent_type == "folder" ? var.roles : []) folder = local.folder_id role = each.key member = var.member } + +resource "google_project_iam_member" "project_parent_iam" { + for_each = toset(var.parent_type == "project" ? var.roles : []) + + project = local.project_id + role = each.key + member = var.member +} diff --git a/0-bootstrap/modules/parent-iam-member/variables.tf b/0-bootstrap/modules/parent-iam-member/variables.tf index d1aa44fd2..9bcbea63a 100644 --- a/0-bootstrap/modules/parent-iam-member/variables.tf +++ b/0-bootstrap/modules/parent-iam-member/variables.tf @@ -15,12 +15,12 @@ */ variable "parent_type" { - description = "Type of the parent resource. valid values are `organization` and `folder`." + description = "Type of the parent resource. valid values are `organization`, `folder`, and `project`." type = string validation { - condition = var.parent_type == "organization" || var.parent_type == "folder" - error_message = "For parent_type only `organization` and `folder` are valid." + condition = var.parent_type == "organization" || var.parent_type == "folder" || var.parent_type == "project" + error_message = "For parent_type only `organization`, `folder`, and `project` are valid." } } diff --git a/0-bootstrap/outputs.tf b/0-bootstrap/outputs.tf index 15b56af98..841d5a1e6 100644 --- a/0-bootstrap/outputs.tf +++ b/0-bootstrap/outputs.tf @@ -49,6 +49,20 @@ output "gcs_bucket_tfstate" { value = module.seed_bootstrap.gcs_bucket_tfstate } +output "common_config" { + description = "Common configuration data to be used in other steps." + value = { + org_id = var.org_id, + parent_folder = var.parent_folder, + billing_account = var.billing_account, + default_region = var.default_region, + project_prefix = var.project_prefix, + folder_prefix = var.folder_prefix + parent_id = local.parent + bootstrap_folder_name = google_folder.bootstrap.name + } +} + /* ---------------------------------------- Specific to cloudbuild_module ---------------------------------------- */ diff --git a/0-bootstrap/sa.tf b/0-bootstrap/sa.tf index 62318d5ba..ca9e4b975 100644 --- a/0-bootstrap/sa.tf +++ b/0-bootstrap/sa.tf @@ -67,6 +67,21 @@ locals { "roles/compute.xpnAdmin", ], } + + granular_sa_seed_project = { + "org" = [ + "roles/storage.objectAdmin", + ], + "env" = [ + "roles/storage.objectAdmin" + ], + "net" = [ + "roles/storage.objectAdmin", + ], + "proj" = [ + "roles/storage.objectAdmin", + ], + } } resource "google_service_account" "terraform-env-sa" { @@ -97,6 +112,16 @@ module "parent_iam_member" { roles = each.value } +module "project_iam_member" { + source = "./modules/parent-iam-member" + for_each = local.granular_sa_seed_project + + member = "serviceAccount:${google_service_account.terraform-env-sa[each.key].email}" + parent_type = "project" + parent_id = module.seed_bootstrap.seed_project_id + roles = each.value +} + resource "google_billing_account_iam_member" "tf_billing_user" { for_each = local.granular_sa diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 701de5557..a14166507 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -6,21 +6,19 @@ | audit\_data\_users | Google Workspace or Cloud Identity group that have access to audit logs. | `string` | n/a | yes | | audit\_logs\_table\_delete\_contents\_on\_destroy | (Optional) If set to true, delete all the tables in the dataset when destroying the resource; otherwise, destroying the resource will fail if tables are present. | `bool` | `false` | no | | audit\_logs\_table\_expiration\_days | Period before tables expire for all audit logs in milliseconds. Default is 30 days. | `number` | `30` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | base\_net\_hub\_project\_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}` for the base net hub project. | `string` | `null` | no | | base\_net\_hub\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the base net hub project. | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | base\_net\_hub\_project\_budget\_amount | The amount to use as the budget for the base net hub project. | `number` | `1000` | no | -| billing\_account | The ID of the billing account to associate this project with | `string` | n/a | yes | | billing\_data\_users | Google Workspace or Cloud Identity group that have access to billing data set. | `string` | n/a | yes | | create\_access\_context\_manager\_access\_policy | Whether to create access context manager access policy | `bool` | `true` | no | | data\_access\_logs\_enabled | Enable Data Access logs of types DATA\_READ, DATA\_WRITE for all GCP services. Enabling Data Access logs might result in your organization being charged for the additional logs usage. See https://cloud.google.com/logging/docs/audit#data-access The ADMIN\_READ logs are enabled by default. | `bool` | `false` | no | -| default\_region | Default region for BigQuery resources. | `string` | n/a | yes | | dns\_hub\_project\_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}` for the DNS hub project. | `string` | `null` | no | | dns\_hub\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the DNS hub project. | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | dns\_hub\_project\_budget\_amount | The amount to use as the budget for the DNS hub project. | `number` | `1000` | 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 | | enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | | enable\_os\_login\_policy | Enable OS Login Organization Policy. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | | gcp\_audit\_viewer | Members are part of an audit team and view audit logs in the logging project. | `string` | `null` | no | | gcp\_billing\_admin\_user | Identity that has billing administrator permissions | `string` | `null` | no | | gcp\_billing\_creator\_user | Identity that can create billing accounts. | `string` | `null` | no | @@ -44,12 +42,9 @@ | org\_billing\_logs\_project\_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}` for the org billing logs project. | `string` | `null` | no | | org\_billing\_logs\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the org billing logs project. | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | org\_billing\_logs\_project\_budget\_amount | The amount to use as the budget for the org billing logs project. | `number` | `1000` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | | org\_secrets\_project\_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}` for the org secrets project. | `string` | `null` | no | | org\_secrets\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the org secrets project. | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | org\_secrets\_project\_budget\_amount | The amount to use as the budget for the org secrets project. | `number` | `1000` | no | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | | restricted\_net\_hub\_project\_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}` for the restricted net hub project. | `string` | `null` | no | | restricted\_net\_hub\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the restricted net hub project. | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | restricted\_net\_hub\_project\_budget\_amount | The amount to use as the budget for the restricted net hub project. | `number` | `1000` | no | @@ -78,6 +73,7 @@ | parent\_resource\_id | The parent resource id | | parent\_resource\_type | The parent resource type | | restricted\_net\_hub\_project\_id | The Restricted Network hub project ID | +| restricted\_net\_hub\_project\_number | The Restricted Network hub project number | | scc\_notification\_name | Name of SCC Notification | | scc\_notifications\_project\_id | The SCC notifications project ID | diff --git a/1-org/envs/shared/folders.tf b/1-org/envs/shared/folders.tf index c956d7263..a4e829d56 100644 --- a/1-org/envs/shared/folders.tf +++ b/1-org/envs/shared/folders.tf @@ -14,15 +14,11 @@ * limitations under the License. */ -locals { - parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} - /****************************************** Top level folders *****************************************/ resource "google_folder" "common" { - display_name = "${var.folder_prefix}-common" + display_name = "${local.folder_prefix}-common" parent = local.parent } diff --git a/1-org/envs/shared/iam.tf b/1-org/envs/shared/iam.tf index ffc44e83e..78464d0b7 100644 --- a/1-org/envs/shared/iam.tf +++ b/1-org/envs/shared/iam.tf @@ -23,8 +23,8 @@ locals { } resource "google_organization_iam_audit_config" "org_config" { - count = var.parent_folder == "" ? 1 : 0 - org_id = var.org_id + count = local.parent_folder == "" ? 1 : 0 + org_id = local.org_id service = "allServices" ################################################################################################### @@ -44,8 +44,8 @@ resource "google_organization_iam_audit_config" "org_config" { } resource "google_folder_iam_audit_config" "folder_config" { - count = var.parent_folder != "" ? 1 : 0 - folder = "folders/${var.parent_folder}" + count = local.parent_folder != "" ? 1 : 0 + folder = "folders/${local.parent_folder}" service = "allServices" ################################################################################################### @@ -97,7 +97,7 @@ resource "google_project_iam_member" "billing_bq_viewer" { *****************************************/ resource "google_organization_iam_member" "billing_viewer" { - org_id = var.org_id + org_id = local.org_id role = "roles/billing.viewer" member = "group:${var.billing_data_users}" } @@ -107,43 +107,43 @@ resource "google_organization_iam_member" "billing_viewer" { *****************************************/ resource "google_organization_iam_member" "organization_viewer" { - count = var.gcp_platform_viewer != null && var.parent_folder == "" ? 1 : 0 - org_id = var.org_id + count = var.gcp_platform_viewer != null && local.parent_folder == "" ? 1 : 0 + org_id = local.org_id role = "roles/viewer" member = "group:${var.gcp_platform_viewer}" } resource "google_folder_iam_member" "organization_viewer" { - count = var.gcp_platform_viewer != null && var.parent_folder != "" ? 1 : 0 - folder = "folders/${var.parent_folder}" + count = var.gcp_platform_viewer != null && local.parent_folder != "" ? 1 : 0 + folder = "folders/${local.parent_folder}" role = "roles/viewer" member = "group:${var.gcp_platform_viewer}" } resource "google_organization_iam_member" "security_reviewer" { - count = var.gcp_security_reviewer != null && var.parent_folder == "" ? 1 : 0 - org_id = var.org_id + count = var.gcp_security_reviewer != null && local.parent_folder == "" ? 1 : 0 + org_id = local.org_id role = "roles/iam.securityReviewer" member = "group:${var.gcp_security_reviewer}" } resource "google_folder_iam_member" "security_reviewer" { - count = var.gcp_security_reviewer != null && var.parent_folder != "" ? 1 : 0 - folder = "folders/${var.parent_folder}" + count = var.gcp_security_reviewer != null && local.parent_folder != "" ? 1 : 0 + folder = "folders/${local.parent_folder}" role = "roles/iam.securityReviewer" member = "group:${var.gcp_security_reviewer}" } resource "google_organization_iam_member" "network_viewer" { - count = var.gcp_network_viewer != null && var.parent_folder == "" ? 1 : 0 - org_id = var.org_id + count = var.gcp_network_viewer != null && local.parent_folder == "" ? 1 : 0 + org_id = local.org_id role = "roles/compute.networkViewer" member = "group:${var.gcp_network_viewer}" } resource "google_folder_iam_member" "network_viewer" { - count = var.gcp_network_viewer != null && var.parent_folder != "" ? 1 : 0 - folder = "folders/${var.parent_folder}" + count = var.gcp_network_viewer != null && local.parent_folder != "" ? 1 : 0 + folder = "folders/${local.parent_folder}" role = "roles/compute.networkViewer" member = "group:${var.gcp_network_viewer}" } @@ -188,29 +188,29 @@ resource "google_project_iam_member" "global_secrets_admin" { *****************************************/ resource "google_organization_iam_member" "org_admin_user" { - count = var.gcp_org_admin_user != null && var.parent_folder == "" ? 1 : 0 - org_id = var.org_id + count = var.gcp_org_admin_user != null && local.parent_folder == "" ? 1 : 0 + org_id = local.org_id role = "roles/resourcemanager.organizationAdmin" member = "user:${var.gcp_org_admin_user}" } resource "google_folder_iam_member" "org_admin_user" { - count = var.gcp_org_admin_user != null && var.parent_folder != "" ? 1 : 0 - folder = "folders/${var.parent_folder}" + count = var.gcp_org_admin_user != null && local.parent_folder != "" ? 1 : 0 + folder = "folders/${local.parent_folder}" role = "roles/resourcemanager.folderAdmin" member = "user:${var.gcp_org_admin_user}" } resource "google_organization_iam_member" "billing_creator_user" { - count = var.gcp_billing_creator_user != null && var.parent_folder == "" ? 1 : 0 - org_id = var.org_id + count = var.gcp_billing_creator_user != null && local.parent_folder == "" ? 1 : 0 + org_id = local.org_id role = "roles/billing.creator" member = "user:${var.gcp_billing_creator_user}" } resource "google_billing_account_iam_member" "billing_admin_user" { count = var.gcp_billing_admin_user != null ? 1 : 0 - billing_account_id = var.billing_account + billing_account_id = local.billing_account role = "roles/billing.admin" member = "user:${var.gcp_billing_admin_user}" } diff --git a/1-org/envs/shared/log_sinks.tf b/1-org/envs/shared/log_sinks.tf index 02dccc000..e88ceca79 100644 --- a/1-org/envs/shared/log_sinks.tf +++ b/1-org/envs/shared/log_sinks.tf @@ -15,8 +15,8 @@ */ locals { - parent_resource_id = var.parent_folder != "" ? var.parent_folder : var.org_id - parent_resource_type = var.parent_folder != "" ? "folder" : "organization" + parent_resource_id = local.parent_folder != "" ? local.parent_folder : local.org_id + parent_resource_type = local.parent_folder != "" ? "folder" : "organization" main_logs_filter = < diff --git a/2-environments/envs/development/main.tf b/2-environments/envs/development/main.tf index edb4ef56a..d80118fea 100644 --- a/2-environments/envs/development/main.tf +++ b/2-environments/envs/development/main.tf @@ -17,13 +17,8 @@ module "env" { source = "../../modules/env_baseline" - env = "development" - environment_code = "d" - - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - org_id = var.org_id - billing_account = var.billing_account + env = "development" + environment_code = "d" monitoring_workspace_users = var.monitoring_workspace_users - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix + backend_bucket = var.backend_bucket } diff --git a/2-environments/envs/development/outputs.tf b/2-environments/envs/development/outputs.tf index 7b759fbc9..3b6b62b29 100644 --- a/2-environments/envs/development/outputs.tf +++ b/2-environments/envs/development/outputs.tf @@ -34,6 +34,11 @@ output "restricted_shared_vpc_project_id" { value = module.env.restricted_shared_vpc_project_id } +output "restricted_shared_vpc_project_number" { + description = "Project number for restricted shared VPC." + value = module.env.restricted_shared_vpc_project_number +} + output "env_secrets_project_id" { description = "Project for environment related secrets." value = module.env.env_secrets_project_id diff --git a/2-environments/envs/development/variables.tf b/2-environments/envs/development/variables.tf index ae48d4e14..41334fc9a 100644 --- a/2-environments/envs/development/variables.tf +++ b/2-environments/envs/development/variables.tf @@ -14,35 +14,12 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" - type = string -} - -variable "billing_account" { - description = "The ID of the billing account to associate this project with" - type = string -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - variable "monitoring_workspace_users" { description = "Google Workspace or Cloud Identity group that have access to Monitoring Workspaces." type = string } -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - default = "fldr" } diff --git a/2-environments/envs/non-production/README.md b/2-environments/envs/non-production/README.md index a75262420..299070cf6 100644 --- a/2-environments/envs/non-production/README.md +++ b/2-environments/envs/non-production/README.md @@ -3,12 +3,8 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| billing\_account | The ID of the billing account to associate this project with | `string` | n/a | yes | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | monitoring\_workspace\_users | Google Workspace or Cloud Identity group that have access to Monitoring Workspaces. | `string` | n/a | yes | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs @@ -19,5 +15,6 @@ | env\_secrets\_project\_id | Project for environment related secrets. | | monitoring\_project\_id | Project for monitoring infra. | | restricted\_shared\_vpc\_project\_id | Project for restricted shared VPC. | +| restricted\_shared\_vpc\_project\_number | Project number for restricted shared VPC. | diff --git a/2-environments/envs/non-production/main.tf b/2-environments/envs/non-production/main.tf index 0a6c9ef98..a232bbf5c 100644 --- a/2-environments/envs/non-production/main.tf +++ b/2-environments/envs/non-production/main.tf @@ -17,13 +17,8 @@ module "env" { source = "../../modules/env_baseline" - env = "non-production" - environment_code = "n" - - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - org_id = var.org_id - billing_account = var.billing_account + env = "non-production" + environment_code = "n" monitoring_workspace_users = var.monitoring_workspace_users - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix + backend_bucket = var.backend_bucket } diff --git a/2-environments/envs/non-production/outputs.tf b/2-environments/envs/non-production/outputs.tf index 7b759fbc9..3b6b62b29 100644 --- a/2-environments/envs/non-production/outputs.tf +++ b/2-environments/envs/non-production/outputs.tf @@ -34,6 +34,11 @@ output "restricted_shared_vpc_project_id" { value = module.env.restricted_shared_vpc_project_id } +output "restricted_shared_vpc_project_number" { + description = "Project number for restricted shared VPC." + value = module.env.restricted_shared_vpc_project_number +} + output "env_secrets_project_id" { description = "Project for environment related secrets." value = module.env.env_secrets_project_id diff --git a/2-environments/envs/non-production/variables.tf b/2-environments/envs/non-production/variables.tf index ae48d4e14..41334fc9a 100644 --- a/2-environments/envs/non-production/variables.tf +++ b/2-environments/envs/non-production/variables.tf @@ -14,35 +14,12 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" - type = string -} - -variable "billing_account" { - description = "The ID of the billing account to associate this project with" - type = string -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - variable "monitoring_workspace_users" { description = "Google Workspace or Cloud Identity group that have access to Monitoring Workspaces." type = string } -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - default = "fldr" } diff --git a/2-environments/envs/production/README.md b/2-environments/envs/production/README.md index 80d483ae4..ceb52971c 100644 --- a/2-environments/envs/production/README.md +++ b/2-environments/envs/production/README.md @@ -3,12 +3,8 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| billing\_account | The ID of the billing account to associate this project with | `string` | n/a | yes | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | monitoring\_workspace\_users | Google Workspace or Cloud Identity group that have access to Monitoring Workspaces. | `string` | n/a | yes | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs @@ -19,6 +15,7 @@ | env\_secrets\_project\_id | Project for environment related secrets. | | monitoring\_project\_id | Project for monitoring infra. | | restricted\_shared\_vpc\_project\_id | Project for restricted shared VPC. | +| restricted\_shared\_vpc\_project\_number | Project number for restricted shared VPC. | diff --git a/2-environments/envs/production/main.tf b/2-environments/envs/production/main.tf index 126b36334..49b2900d9 100644 --- a/2-environments/envs/production/main.tf +++ b/2-environments/envs/production/main.tf @@ -17,13 +17,8 @@ module "env" { source = "../../modules/env_baseline" - env = "production" - environment_code = "p" - - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - org_id = var.org_id - billing_account = var.billing_account + env = "production" + environment_code = "p" monitoring_workspace_users = var.monitoring_workspace_users - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix + backend_bucket = var.backend_bucket } diff --git a/2-environments/envs/production/outputs.tf b/2-environments/envs/production/outputs.tf index 7b759fbc9..3b6b62b29 100644 --- a/2-environments/envs/production/outputs.tf +++ b/2-environments/envs/production/outputs.tf @@ -34,6 +34,11 @@ output "restricted_shared_vpc_project_id" { value = module.env.restricted_shared_vpc_project_id } +output "restricted_shared_vpc_project_number" { + description = "Project number for restricted shared VPC." + value = module.env.restricted_shared_vpc_project_number +} + output "env_secrets_project_id" { description = "Project for environment related secrets." value = module.env.env_secrets_project_id diff --git a/2-environments/envs/production/variables.tf b/2-environments/envs/production/variables.tf index ae48d4e14..41334fc9a 100644 --- a/2-environments/envs/production/variables.tf +++ b/2-environments/envs/production/variables.tf @@ -14,35 +14,12 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" - type = string -} - -variable "billing_account" { - description = "The ID of the billing account to associate this project with" - type = string -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - variable "monitoring_workspace_users" { description = "Google Workspace or Cloud Identity group that have access to Monitoring Workspaces." type = string } -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - default = "fldr" } diff --git a/2-environments/modules/env_baseline/README.md b/2-environments/modules/env_baseline/README.md index 78ddd849e..704103142 100644 --- a/2-environments/modules/env_baseline/README.md +++ b/2-environments/modules/env_baseline/README.md @@ -3,20 +3,16 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | base\_network\_project\_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}` for the base networks project | `string` | `null` | no | | base\_network\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the base networks project | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | base\_network\_project\_budget\_amount | The amount to use as the budget for the base networks project | `number` | `1000` | no | -| billing\_account | The ID of the billing account to associate this project with | `string` | n/a | yes | | 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 | -| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | | monitoring\_project\_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}` for the monitoring project. | `string` | `null` | no | | monitoring\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the monitoring project. | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | monitoring\_project\_budget\_amount | The amount to use as the budget for the monitoring project. | `number` | `1000` | no | | monitoring\_workspace\_users | Google Workspace or Cloud Identity group that have access to Monitoring Workspaces. | `string` | n/a | yes | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_id | The parent folder or org for environments | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. | `string` | `"prj"` | no | | restricted\_network\_project\_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}` for the restricted networks project | `string` | `null` | no | | restricted\_network\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the restricted networks project. | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | | restricted\_network\_project\_budget\_amount | The amount to use as the budget for the restricted networks project. | `number` | `1000` | no | @@ -33,5 +29,6 @@ | env\_secrets\_project\_id | Project for environment secrets. | | monitoring\_project\_id | Project for monitoring infra. | | restricted\_shared\_vpc\_project\_id | Project for restricted shared VPC network. | +| restricted\_shared\_vpc\_project\_number | Project number for restricted shared VPC. | diff --git a/2-environments/modules/env_baseline/folders.tf b/2-environments/modules/env_baseline/folders.tf index 01b23db9c..1974e68e8 100644 --- a/2-environments/modules/env_baseline/folders.tf +++ b/2-environments/modules/env_baseline/folders.tf @@ -14,21 +14,12 @@ * limitations under the License. */ -/****************************************** - Folder lookups -*****************************************/ - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = local.parent -} - /****************************************** Environment Folder *****************************************/ resource "google_folder" "env" { - display_name = "${var.folder_prefix}-${var.env}" + display_name = "${local.folder_prefix}-${var.env}" parent = local.parent } diff --git a/2-environments/modules/env_baseline/main.tf b/2-environments/modules/env_baseline/main.tf index 2e96b2b24..36e7003d7 100644 --- a/2-environments/modules/env_baseline/main.tf +++ b/2-environments/modules/env_baseline/main.tf @@ -15,5 +15,20 @@ */ locals { - parent = var.parent_id + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder + parent = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } } diff --git a/2-environments/modules/env_baseline/monitoring.tf b/2-environments/modules/env_baseline/monitoring.tf index 6e8b9cf27..26eb37a09 100644 --- a/2-environments/modules/env_baseline/monitoring.tf +++ b/2-environments/modules/env_baseline/monitoring.tf @@ -22,9 +22,9 @@ module "monitoring_project" { source = "terraform-google-modules/project-factory/google" version = "~> 13.0" random_project_id = true - name = "${var.project_prefix}-${var.environment_code}-monitoring" - org_id = var.org_id - billing_account = var.billing_account + name = "${local.project_prefix}-${var.environment_code}-monitoring" + org_id = local.org_id + billing_account = local.billing_account folder_id = google_folder.env.id disable_services_on_destroy = false depends_on = [time_sleep.wait_30_seconds] diff --git a/2-environments/modules/env_baseline/networking.tf b/2-environments/modules/env_baseline/networking.tf index a1b93dbd6..e9315694f 100644 --- a/2-environments/modules/env_baseline/networking.tf +++ b/2-environments/modules/env_baseline/networking.tf @@ -22,9 +22,9 @@ module "base_shared_vpc_host_project" { source = "terraform-google-modules/project-factory/google" version = "~> 13.0" random_project_id = true - name = format("%s-%s-shared-base", var.project_prefix, var.environment_code) - org_id = var.org_id - billing_account = var.billing_account + name = format("%s-%s-shared-base", local.project_prefix, var.environment_code) + org_id = local.org_id + billing_account = local.billing_account folder_id = google_folder.env.id disable_services_on_destroy = false depends_on = [time_sleep.wait_30_seconds] @@ -55,9 +55,9 @@ module "restricted_shared_vpc_host_project" { source = "terraform-google-modules/project-factory/google" version = "~> 13.0" random_project_id = true - name = format("%s-%s-shared-restricted", var.project_prefix, var.environment_code) - org_id = var.org_id - billing_account = var.billing_account + name = format("%s-%s-shared-restricted", local.project_prefix, var.environment_code) + org_id = local.org_id + billing_account = local.billing_account folder_id = google_folder.env.id disable_services_on_destroy = false depends_on = [time_sleep.wait_30_seconds] diff --git a/2-environments/modules/env_baseline/outputs.tf b/2-environments/modules/env_baseline/outputs.tf index 9f242ac37..ca8b01447 100644 --- a/2-environments/modules/env_baseline/outputs.tf +++ b/2-environments/modules/env_baseline/outputs.tf @@ -34,6 +34,11 @@ output "restricted_shared_vpc_project_id" { value = module.restricted_shared_vpc_host_project.project_id } +output "restricted_shared_vpc_project_number" { + description = "Project number for restricted shared VPC." + value = module.restricted_shared_vpc_host_project.project_number +} + output "env_secrets_project_id" { description = "Project for environment secrets." value = module.env_secrets.project_id diff --git a/2-environments/modules/env_baseline/secrets.tf b/2-environments/modules/env_baseline/secrets.tf index aa89ab71f..aaa7f542c 100644 --- a/2-environments/modules/env_baseline/secrets.tf +++ b/2-environments/modules/env_baseline/secrets.tf @@ -24,9 +24,9 @@ module "env_secrets" { version = "~> 13.0" random_project_id = true default_service_account = "deprivilege" - name = "${var.project_prefix}-${var.environment_code}-secrets" - org_id = var.org_id - billing_account = var.billing_account + name = "${local.project_prefix}-${var.environment_code}-secrets" + org_id = local.org_id + billing_account = local.billing_account folder_id = google_folder.env.id disable_services_on_destroy = false activate_apis = ["logging.googleapis.com", "secretmanager.googleapis.com"] diff --git a/2-environments/modules/env_baseline/variables.tf b/2-environments/modules/env_baseline/variables.tf index 2f61cda88..759b79bdf 100644 --- a/2-environments/modules/env_baseline/variables.tf +++ b/2-environments/modules/env_baseline/variables.tf @@ -24,18 +24,8 @@ variable "environment_code" { description = "A short form of the folder level resources (environment) within the Google Cloud organization (ex. d)." } -variable "parent_id" { - description = "The parent folder or org for environments" - type = string -} - -variable "org_id" { - description = "The organization id for the associated services" - type = string -} - -variable "billing_account" { - description = "The ID of the billing account to associate this project with" +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string } @@ -115,15 +105,3 @@ variable "secret_project_budget_amount" { type = number default = 1000 } - -variable "project_prefix" { - description = "Name prefix to use for projects created." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created." - type = string - default = "fldr" -} diff --git a/2-environments/terraform.example.tfvars b/2-environments/terraform.example.tfvars index 2d5ded5a6..d725138a7 100644 --- a/2-environments/terraform.example.tfvars +++ b/2-environments/terraform.example.tfvars @@ -14,12 +14,7 @@ * limitations under the License. */ -org_id = "000000000000" - -billing_account = "000000-000000-000000" monitoring_workspace_users = "gcp-monitoring-admins@example.com" -// Optional - for an organization with existing projects or for development/validation. -// Must be the same value used in previous steps. -//parent_folder = "01234567890" +backend_bucket = "" diff --git a/3-networks-dual-svpc/common.auto.example.tfvars b/3-networks-dual-svpc/common.auto.example.tfvars index 8d87e4bd3..395729456 100644 --- a/3-networks-dual-svpc/common.auto.example.tfvars +++ b/3-networks-dual-svpc/common.auto.example.tfvars @@ -14,14 +14,9 @@ * limitations under the License. */ -org_id = "000000000000" - terraform_service_account = "terraform-net-sa@prj-b-seed-2334.iam.gserviceaccount.com" // The DNS name of peering managed zone. Must end with a period. domain = "example.com." -// Optional - for an organization with existing projects or for development/validation. -// Must be the same value used in previous steps. -//parent_folder = "000000000000" - +backend_bucket = "" diff --git a/3-networks-dual-svpc/envs/development/README.md b/3-networks-dual-svpc/envs/development/README.md index c7a1f07bf..92d1a8ef8 100644 --- a/3-networks-dual-svpc/envs/development/README.md +++ b/3-networks-dual-svpc/envs/development/README.md @@ -16,16 +16,15 @@ The purpose of this step is to set up base and restricted shared VPCs with defau | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `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 | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | terraform\_service\_account | Service account email of the account to be added to the VPC-SC perimeter. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | base\_host\_project\_id | The base host project ID | | base\_network\_name | The name of the VPC being created | | base\_network\_self\_link | The URI of the VPC being created | diff --git a/3-networks-dual-svpc/envs/development/main.tf b/3-networks-dual-svpc/envs/development/main.tf index 80ce4fb47..d100938b1 100644 --- a/3-networks-dual-svpc/envs/development/main.tf +++ b/3-networks-dual-svpc/envs/development/main.tf @@ -66,13 +66,11 @@ module "base_env" { env = local.env environment_code = local.environment_code - org_id = var.org_id access_context_manager_policy_id = var.access_context_manager_policy_id members = ["serviceAccount:${var.terraform_service_account}"] default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - parent_folder = var.parent_folder enable_partner_interconnect = false base_private_service_cidr = local.base_private_service_cidr base_subnet_primary_ranges = local.base_subnet_primary_ranges @@ -80,5 +78,6 @@ module "base_env" { restricted_private_service_cidr = local.restricted_private_service_cidr restricted_subnet_primary_ranges = local.restricted_subnet_primary_ranges restricted_subnet_secondary_ranges = local.restricted_subnet_secondary_ranges + backend_bucket = var.backend_bucket } diff --git a/3-networks-dual-svpc/envs/development/outputs.tf b/3-networks-dual-svpc/envs/development/outputs.tf index 470ab53ee..bcf18cd1d 100644 --- a/3-networks-dual-svpc/envs/development/outputs.tf +++ b/3-networks-dual-svpc/envs/development/outputs.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +output "access_context_manager_policy_id" { + description = "Access Context Manager Policy ID." + value = var.access_context_manager_policy_id +} + /********************* Restricted Outputs *********************/ diff --git a/3-networks-dual-svpc/envs/development/variables.tf b/3-networks-dual-svpc/envs/development/variables.tf index 44734a1fa..59675977b 100644 --- a/3-networks-dual-svpc/envs/development/variables.tf +++ b/3-networks-dual-svpc/envs/development/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "access_context_manager_policy_id" { @@ -33,15 +33,3 @@ variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} diff --git a/3-networks-dual-svpc/envs/non-production/README.md b/3-networks-dual-svpc/envs/non-production/README.md index 0123d7ed2..8aff81436 100644 --- a/3-networks-dual-svpc/envs/non-production/README.md +++ b/3-networks-dual-svpc/envs/non-production/README.md @@ -16,16 +16,15 @@ The purpose of this step is to set up base and restricted shared VPCs with defau | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `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 | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | terraform\_service\_account | Service account email of the account to be added to the VPC-SC perimeter. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | base\_host\_project\_id | The base host project ID | | base\_network\_name | The name of the VPC being created | | base\_network\_self\_link | The URI of the VPC being created | diff --git a/3-networks-dual-svpc/envs/non-production/main.tf b/3-networks-dual-svpc/envs/non-production/main.tf index a3f0a9fb8..bf9c432d1 100644 --- a/3-networks-dual-svpc/envs/non-production/main.tf +++ b/3-networks-dual-svpc/envs/non-production/main.tf @@ -66,13 +66,11 @@ module "base_env" { env = local.env environment_code = local.environment_code - org_id = var.org_id access_context_manager_policy_id = var.access_context_manager_policy_id members = ["serviceAccount:${var.terraform_service_account}"] default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - parent_folder = var.parent_folder enable_partner_interconnect = false base_private_service_cidr = local.base_private_service_cidr base_subnet_primary_ranges = local.base_subnet_primary_ranges @@ -80,4 +78,5 @@ module "base_env" { restricted_private_service_cidr = local.restricted_private_service_cidr restricted_subnet_primary_ranges = local.restricted_subnet_primary_ranges restricted_subnet_secondary_ranges = local.restricted_subnet_secondary_ranges + backend_bucket = var.backend_bucket } diff --git a/3-networks-dual-svpc/envs/non-production/outputs.tf b/3-networks-dual-svpc/envs/non-production/outputs.tf index 470ab53ee..bcf18cd1d 100644 --- a/3-networks-dual-svpc/envs/non-production/outputs.tf +++ b/3-networks-dual-svpc/envs/non-production/outputs.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +output "access_context_manager_policy_id" { + description = "Access Context Manager Policy ID." + value = var.access_context_manager_policy_id +} + /********************* Restricted Outputs *********************/ diff --git a/3-networks-dual-svpc/envs/non-production/variables.tf b/3-networks-dual-svpc/envs/non-production/variables.tf index 221151a3d..59675977b 100644 --- a/3-networks-dual-svpc/envs/non-production/variables.tf +++ b/3-networks-dual-svpc/envs/non-production/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "access_context_manager_policy_id" { @@ -33,16 +33,3 @@ variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - diff --git a/3-networks-dual-svpc/envs/production/README.md b/3-networks-dual-svpc/envs/production/README.md index 1a2506116..b4decce77 100644 --- a/3-networks-dual-svpc/envs/production/README.md +++ b/3-networks-dual-svpc/envs/production/README.md @@ -16,16 +16,15 @@ The purpose of this step is to set up base and restricted shared VPCs with defau | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `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 | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | terraform\_service\_account | Service account email of the account to be added to the VPC-SC perimeter. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | base\_host\_project\_id | The base host project ID | | base\_network\_name | The name of the VPC being created | | base\_network\_self\_link | The URI of the VPC being created | diff --git a/3-networks-dual-svpc/envs/production/main.tf b/3-networks-dual-svpc/envs/production/main.tf index 6eabaf09d..3265b35d1 100644 --- a/3-networks-dual-svpc/envs/production/main.tf +++ b/3-networks-dual-svpc/envs/production/main.tf @@ -66,13 +66,11 @@ module "base_env" { env = local.env environment_code = local.environment_code - org_id = var.org_id access_context_manager_policy_id = var.access_context_manager_policy_id members = ["serviceAccount:${var.terraform_service_account}"] default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - parent_folder = var.parent_folder enable_partner_interconnect = false base_private_service_cidr = local.base_private_service_cidr base_subnet_primary_ranges = local.base_subnet_primary_ranges @@ -80,4 +78,5 @@ module "base_env" { restricted_private_service_cidr = local.restricted_private_service_cidr restricted_subnet_primary_ranges = local.restricted_subnet_primary_ranges restricted_subnet_secondary_ranges = local.restricted_subnet_secondary_ranges + backend_bucket = var.backend_bucket } diff --git a/3-networks-dual-svpc/envs/production/outputs.tf b/3-networks-dual-svpc/envs/production/outputs.tf index 470ab53ee..bcf18cd1d 100644 --- a/3-networks-dual-svpc/envs/production/outputs.tf +++ b/3-networks-dual-svpc/envs/production/outputs.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +output "access_context_manager_policy_id" { + description = "Access Context Manager Policy ID." + value = var.access_context_manager_policy_id +} + /********************* Restricted Outputs *********************/ diff --git a/3-networks-dual-svpc/envs/production/variables.tf b/3-networks-dual-svpc/envs/production/variables.tf index 44734a1fa..59675977b 100644 --- a/3-networks-dual-svpc/envs/production/variables.tf +++ b/3-networks-dual-svpc/envs/production/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "access_context_manager_policy_id" { @@ -33,15 +33,3 @@ variable "domain" { type = string description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} diff --git a/3-networks-dual-svpc/envs/shared/README.md b/3-networks-dual-svpc/envs/shared/README.md index 26a85e184..9d3158a52 100644 --- a/3-networks-dual-svpc/envs/shared/README.md +++ b/3-networks-dual-svpc/envs/shared/README.md @@ -13,6 +13,7 @@ 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | base\_hub\_dns\_enable\_inbound\_forwarding | Toggle inbound query forwarding for Base Hub VPC DNS. | `bool` | `true` | no | | base\_hub\_dns\_enable\_logging | Toggle DNS logging for Base Hub VPC DNS. | `bool` | `true` | no | | base\_hub\_firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls in Base Hub VPC. | `bool` | `true` | no | @@ -25,9 +26,6 @@ The purpose of this step is to set up the global [DNS Hub](https://cloud.google. | domain | The DNS name of forwarding managed zone, for instance 'example.com'. Must end with a period. | `string` | n/a | yes | | enable\_partner\_interconnect | Enable Partner Interconnect in the environment. | `bool` | `false` | no | | firewall\_policies\_enable\_logging | Toggle hierarchical firewall logging. | `bool` | `true` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | preactivate\_partner\_interconnect | Preactivate Partner Interconnect VLAN attachment in the environment. | `bool` | `false` | no | | restricted\_hub\_dns\_enable\_inbound\_forwarding | Toggle inbound query forwarding for Restricted Hub VPC DNS. | `bool` | `true` | no | | restricted\_hub\_dns\_enable\_logging | Toggle DNS logging for Restricted Hub VPC DNS. | `bool` | `true` | no | diff --git a/3-networks-dual-svpc/envs/shared/dns-hub.tf b/3-networks-dual-svpc/envs/shared/dns-hub.tf index 343a0a45e..efdce62f1 100644 --- a/3-networks-dual-svpc/envs/shared/dns-hub.tf +++ b/3-networks-dual-svpc/envs/shared/dns-hub.tf @@ -14,39 +14,6 @@ * limitations under the License. */ -locals { - dns_hub_project_id = data.google_projects.dns_hub.projects[0].project_id -} - -data "google_active_folder" "bootstrap" { - display_name = "${var.folder_prefix}-bootstrap" - parent = local.parent_id -} - -data "google_active_folder" "development" { - display_name = "${var.folder_prefix}-development" - parent = local.parent_id -} - -data "google_active_folder" "production" { - display_name = "${var.folder_prefix}-production" - parent = local.parent_id -} - -data "google_active_folder" "non-production" { - display_name = "${var.folder_prefix}-non-production" - parent = local.parent_id -} - -/****************************************** - DNS Hub Project -*****************************************/ - -data "google_projects" "dns_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-dns-hub lifecycleState=ACTIVE" -} - - /****************************************** DNS Hub VPC *****************************************/ diff --git a/3-networks-dual-svpc/envs/shared/hierarchical_firewall.tf b/3-networks-dual-svpc/envs/shared/hierarchical_firewall.tf index f859dc5f1..d03fc4e38 100644 --- a/3-networks-dual-svpc/envs/shared/hierarchical_firewall.tf +++ b/3-networks-dual-svpc/envs/shared/hierarchical_firewall.tf @@ -16,14 +16,14 @@ module "hierarchical_firewall_policy" { source = "../../modules/hierarchical_firewall_policy/" - parent = data.google_active_folder.common.name + parent = local.common_folder_name name = "common-firewall-rules" associations = [ - data.google_active_folder.common.name, - data.google_active_folder.bootstrap.name, - data.google_active_folder.development.name, - data.google_active_folder.production.name, - data.google_active_folder.non-production.name, + local.common_folder_name, + local.bootstrap_folder_name, + local.development_folder_name, + local.production_folder_name, + local.non_production_folder_name, ] rules = { delegate-rfc1918-ingress = { diff --git a/3-networks-dual-svpc/envs/shared/interconnect.tf.example b/3-networks-dual-svpc/envs/shared/interconnect.tf.example index 783e353ec..2fbf40e3f 100644 --- a/3-networks-dual-svpc/envs/shared/interconnect.tf.example +++ b/3-networks-dual-svpc/envs/shared/interconnect.tf.example @@ -17,9 +17,8 @@ module "dns_hub_interconnect" { source = "../../modules/dedicated_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "c-dns-hub" + vpc_name = "c-dns-hub" + interconnect_project_id = local.interconnect_project_id region1 = local.default_region1 region1_router1_name = module.dns_hub_region1_router1.router.name diff --git a/3-networks-dual-svpc/envs/shared/main.tf b/3-networks-dual-svpc/envs/shared/main.tf index b5816257f..220224a42 100644 --- a/3-networks-dual-svpc/envs/shared/main.tf +++ b/3-networks-dual-svpc/envs/shared/main.tf @@ -15,15 +15,63 @@ */ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - env = "common" - environment_code = "c" - bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" - default_region1 = "us-west1" - default_region2 = "us-central1" + env = "common" + environment_code = "c" + bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" + default_region1 = "us-west1" + default_region2 = "us-central1" + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix + dns_hub_project_id = data.terraform_remote_state.org.outputs.dns_hub_project_id + interconnect_project_id = data.terraform_remote_state.org.outputs.interconnect_project_id + parent_id = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + bootstrap_folder_name = data.terraform_remote_state.bootstrap.outputs.common_config.bootstrap_folder_name + common_folder_name = data.terraform_remote_state.org.outputs.common_folder_name + development_folder_name = data.terraform_remote_state.env_development.outputs.env_folder + non_production_folder_name = data.terraform_remote_state.env_non_production.outputs.env_folder + production_folder_name = data.terraform_remote_state.env_production.outputs.env_folder } -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-${local.env}" - parent = local.parent_id +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } +} + +data "terraform_remote_state" "org" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/org/state" + } +} + +data "terraform_remote_state" "env_development" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/development" + } +} + +data "terraform_remote_state" "env_non_production" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/non-production" + } +} + +data "terraform_remote_state" "env_production" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/production" + } } diff --git a/3-networks-dual-svpc/envs/shared/partner_interconnect.tf.example b/3-networks-dual-svpc/envs/shared/partner_interconnect.tf.example index 49edebb0d..25ec9e5b2 100644 --- a/3-networks-dual-svpc/envs/shared/partner_interconnect.tf.example +++ b/3-networks-dual-svpc/envs/shared/partner_interconnect.tf.example @@ -15,14 +15,12 @@ */ module "shared_restricted_interconnect" { - source = "../../modules/partner_interconnect" + source = "../../modules/partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${local.environment_code}-shared-restricted" - environment = local.env - vpc_type = "restricted" - preactivate = var.preactivate_partner_interconnect + attachment_project_id = local.restricted_net_hub_project_id + vpc_name = "${local.environment_code}-shared-restricted" + vpc_type = "restricted" + preactivate = var.preactivate_partner_interconnect region1 = local.default_region1 region1_router1_name = module.restricted_shared_vpc[0].region1_router1.router.name @@ -36,8 +34,6 @@ module "shared_restricted_interconnect" { region2_router2_name = module.restricted_shared_vpc[0].region2_router2.router.name region2_interconnect2_location = "lax-zone1-403" - folder_prefix = var.folder_prefix - cloud_router_labels = { vlan_1 = "cr5", vlan_2 = "cr6", @@ -47,14 +43,12 @@ module "shared_restricted_interconnect" { } module "shared_base_interconnect" { - source = "../../modules/partner_interconnect" + source = "../../modules/partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${local.environment_code}-shared-base" - environment = local.env - vpc_type = "base" - preactivate = var.preactivate_partner_interconnect + attachment_project_id = local.base_net_hub_project_id + vpc_name = "${local.environment_code}-shared-base" + vpc_type = "base" + preactivate = var.preactivate_partner_interconnect region1 = local.default_region1 region1_router1_name = module.base_shared_vpc[0].region1_router1.router.name @@ -68,8 +62,6 @@ module "shared_base_interconnect" { region2_router2_name = module.base_shared_vpc[0].region2_router2.router.name region2_interconnect2_location = "lax-zone1-403" - folder_prefix = var.folder_prefix - cloud_router_labels = { vlan_1 = "cr1", vlan_2 = "cr2", diff --git a/3-networks-dual-svpc/envs/shared/variables.tf b/3-networks-dual-svpc/envs/shared/variables.tf index 43a1cd7a9..c09430bb9 100644 --- a/3-networks-dual-svpc/envs/shared/variables.tf +++ b/3-networks-dual-svpc/envs/shared/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "terraform_service_account" { @@ -57,18 +57,6 @@ variable "target_name_server_addresses" { type = list(string) } -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - variable "restricted_hub_windows_activation_enabled" { type = bool description = "Enable Windows license activation for Windows workloads in Restricted Hub." diff --git a/3-networks-dual-svpc/modules/base_env/README.md b/3-networks-dual-svpc/modules/base_env/README.md index 83511a833..446074288 100644 --- a/3-networks-dual-svpc/modules/base_env/README.md +++ b/3-networks-dual-svpc/modules/base_env/README.md @@ -4,6 +4,7 @@ | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | base\_private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Base Shared Vpc. | `string` | n/a | yes | | base\_subnet\_primary\_ranges | The base subnet primary IPTs ranges to the Base Shared Vpc. | `map(string)` | n/a | yes | | base\_subnet\_secondary\_ranges | The base subnet secondary IPTs ranges to the Base Shared Vpc. | `map(list(map(string)))` | n/a | yes | @@ -13,10 +14,7 @@ | 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 | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | | members | An allowed list of members (users, service accounts)to be include in the VPC-SC 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 | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | restricted\_private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Restricted Shared Vpc. | `string` | n/a | yes | | restricted\_subnet\_primary\_ranges | The base subnet primary IPTs ranges to the Restricted Shared Vpc. | `map(string)` | n/a | yes | | restricted\_subnet\_secondary\_ranges | The base subnet secondary IPTs ranges to the Restricted Shared Vpc | `map(list(map(string)))` | n/a | yes | diff --git a/3-networks-dual-svpc/modules/base_env/interconnect.tf.example b/3-networks-dual-svpc/modules/base_env/interconnect.tf.example index 75c29ceb0..1cd9df56e 100644 --- a/3-networks-dual-svpc/modules/base_env/interconnect.tf.example +++ b/3-networks-dual-svpc/modules/base_env/interconnect.tf.example @@ -17,9 +17,8 @@ module "shared_restricted_interconnect" { source = "../dedicated_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-restricted" + vpc_name = "${var.environment_code}-shared-restricted" + interconnect_project_id = local.interconnect_project_id region1 = var.default_region1 region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name @@ -59,9 +58,8 @@ module "shared_restricted_interconnect" { module "shared_base_interconnect" { source = "../dedicated_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-base" + vpc_name = "${var.environment_code}-shared-base" + interconnect_project_id = local.interconnect_project_id region1 = var.default_region1 region1_router1_name = module.base_shared_vpc.region1_router1.router.name diff --git a/3-networks-dual-svpc/modules/base_env/main.tf b/3-networks-dual-svpc/modules/base_env/main.tf index f462a3f99..02bd8ccf4 100644 --- a/3-networks-dual-svpc/modules/base_env/main.tf +++ b/3-networks-dual-svpc/modules/base_env/main.tf @@ -15,11 +15,21 @@ */ locals { - restricted_project_id = data.google_projects.restricted_host_project.projects[0].project_id - restricted_project_number = data.google_project.restricted_host_project.number - base_project_id = data.google_projects.base_host_project.projects[0].project_id - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder + parent_id = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix + restricted_project_id = data.terraform_remote_state.environments_env.outputs.restricted_shared_vpc_project_id + restricted_project_number = data.terraform_remote_state.environments_env.outputs.restricted_shared_vpc_project_number + base_project_id = data.terraform_remote_state.environments_env.outputs.base_shared_vpc_project_id + env_secret_project_id = data.terraform_remote_state.environments_env.outputs.env_secrets_project_id + interconnect_project_id = data.terraform_remote_state.org.outputs.interconnect_project_id + dns_hub_project_id = data.terraform_remote_state.org.outputs.dns_hub_project_id + + + bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" /* * Base network ranges */ @@ -32,25 +42,40 @@ locals { restricted_hub_subnet_ranges = ["10.8.0.0/24", "10.9.0.0/24"] } -data "google_active_folder" "env" { - display_name = "${var.folder_prefix}-${var.env}" - parent = local.parent_id +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } } -/****************************************** - VPC Host Projects -*****************************************/ +data "terraform_remote_state" "org" { + backend = "gcs" -data "google_projects" "restricted_host_project" { - filter = "parent.id:${split("/", data.google_active_folder.env.name)[1]} labels.application_name=restricted-shared-vpc-host labels.environment=${var.env} lifecycleState=ACTIVE" + config = { + bucket = var.backend_bucket + prefix = "terraform/org/state" + } } -data "google_project" "restricted_host_project" { - project_id = data.google_projects.restricted_host_project.projects[0].project_id +data "terraform_remote_state" "network_shared" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/networks/envs/shared" + } } -data "google_projects" "base_host_project" { - filter = "parent.id:${split("/", data.google_active_folder.env.name)[1]} labels.application_name=base-shared-vpc-host labels.environment=${var.env} lifecycleState=ACTIVE" +data "terraform_remote_state" "environments_env" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/${var.env}" + } } /****************************************** @@ -59,14 +84,15 @@ data "google_projects" "base_host_project" { module "restricted_shared_vpc" { source = "../restricted_shared_vpc" project_id = local.restricted_project_id + dns_hub_project_id = local.dns_hub_project_id project_number = local.restricted_project_number environment_code = var.environment_code access_context_manager_policy_id = var.access_context_manager_policy_id restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] members = var.members private_service_cidr = var.restricted_private_service_cidr - org_id = var.org_id - parent_folder = var.parent_folder + org_id = local.org_id + parent_folder = local.parent_folder bgp_asn_subnet = local.bgp_asn_number default_region1 = var.default_region1 default_region2 = var.default_region2 @@ -104,10 +130,11 @@ module "restricted_shared_vpc" { module "base_shared_vpc" { source = "../base_shared_vpc" project_id = local.base_project_id + dns_hub_project_id = local.dns_hub_project_id environment_code = var.environment_code private_service_cidr = var.base_private_service_cidr - org_id = var.org_id - parent_folder = var.parent_folder + org_id = local.org_id + parent_folder = local.parent_folder default_region1 = var.default_region1 default_region2 = var.default_region2 domain = var.domain diff --git a/3-networks-dual-svpc/modules/base_env/partner_interconnect.tf.example b/3-networks-dual-svpc/modules/base_env/partner_interconnect.tf.example index 4db0be5ea..e6b656a4e 100644 --- a/3-networks-dual-svpc/modules/base_env/partner_interconnect.tf.example +++ b/3-networks-dual-svpc/modules/base_env/partner_interconnect.tf.example @@ -15,14 +15,12 @@ */ module "shared_restricted_interconnect" { - source = "../partner_interconnect" + source = "../partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-restricted" - environment = var.env - vpc_type = "restricted" - preactivate = true + attachment_project_id = local.restricted_project_id + vpc_name = "${var.environment_code}-shared-restricted" + vpc_type = "restricted" + preactivate = true region1 = var.default_region1 region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name @@ -45,14 +43,12 @@ module "shared_restricted_interconnect" { } module "shared_base_interconnect" { - source = "../partner_interconnect" + source = "../partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-base" - environment = var.env - vpc_type = "base" - preactivate = true + attachment_project_id = local.base_project_id + vpc_name = "${var.environment_code}-shared-base" + vpc_type = "base" + preactivate = true region1 = var.default_region1 region1_router1_name = module.base_shared_vpc.region1_router1.router.name diff --git a/3-networks-dual-svpc/modules/base_env/variables.tf b/3-networks-dual-svpc/modules/base_env/variables.tf index 03b54d2be..7a2c9949a 100644 --- a/3-networks-dual-svpc/modules/base_env/variables.tf +++ b/3-networks-dual-svpc/modules/base_env/variables.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." + type = string +} + variable "env" { description = "The environment to prepare (ex. development)" type = string @@ -24,11 +29,6 @@ variable "environment_code" { description = "A short form of the folder level resources (environment) within the Google Cloud organization (ex. d)." } -variable "org_id" { - type = string - description = "Organization ID" -} - 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)\"`." @@ -49,18 +49,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - variable "enable_partner_interconnect" { description = "Enable Partner Interconnect in the environment." type = bool diff --git a/3-networks-dual-svpc/modules/base_env/vpn.tf.example b/3-networks-dual-svpc/modules/base_env/vpn.tf.example index ca6190c69..f4e69cb08 100644 --- a/3-networks-dual-svpc/modules/base_env/vpn.tf.example +++ b/3-networks-dual-svpc/modules/base_env/vpn.tf.example @@ -17,19 +17,16 @@ module "shared_base_vpn" { source = "../vpn-ha" - project_id = local.base_project_id - default_region1 = var.default_region1 - default_region2 = var.default_region2 - vpc_name = "${var.environment_code}-shared-base" - region1_router1_name = module.base_shared_vpc.region1_router1.router.name - region1_router2_name = module.base_shared_vpc.region1_router2.router.name - region2_router1_name = module.base_shared_vpc.region2_router1.router.name - region2_router2_name = module.base_shared_vpc.region2_router2.router.name - environment = var.env - parent_folder = var.parent_folder - org_id = var.org_id - vpn_psk_secret_name = "" - folder_prefix = var.folder_prefix + project_id = local.base_project_id + env_secret_project_id = local.env_secret_project_id + default_region1 = var.default_region1 + default_region2 = var.default_region2 + vpc_name = "${var.environment_code}-shared-base" + region1_router1_name = module.base_shared_vpc.region1_router1.router.name + region1_router2_name = module.base_shared_vpc.region1_router2.router.name + region2_router1_name = module.base_shared_vpc.region2_router1.router.name + region2_router2_name = module.base_shared_vpc.region2_router2.router.name + vpn_psk_secret_name = "" on_prem_router_ip_address1 = "<8.8.8.8>" # on-prem router ip address 1 on_prem_router_ip_address2 = "<8.8.8.8>" # on-prem router ip address 2 @@ -63,18 +60,16 @@ module "shared_base_vpn" { module "shared_restricted_vpn" { source = "../vpn-ha" - project_id = local.restricted_project_id - default_region1 = var.default_region1 - default_region2 = var.default_region2 - vpc_name = "${var.environment_code}-shared-restricted" - region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name - region1_router2_name = module.restricted_shared_vpc.region1_router2.router.name - region2_router1_name = module.restricted_shared_vpc.region2_router1.router.name - region2_router2_name = module.restricted_shared_vpc.region2_router2.router.name - environment = var.env - parent_folder = var.parent_folder - org_id = var.org_id - vpn_psk_secret_name = "" + project_id = local.restricted_project_id + env_secret_project_id = local.env_secret_project_id + default_region1 = var.default_region1 + default_region2 = var.default_region2 + vpc_name = "${var.environment_code}-shared-restricted" + region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name + region1_router2_name = module.restricted_shared_vpc.region1_router2.router.name + region2_router1_name = module.restricted_shared_vpc.region2_router1.router.name + region2_router2_name = module.restricted_shared_vpc.region2_router2.router.name + vpn_psk_secret_name = "" on_prem_router_ip_address1 = "<8.8.8.8>" # on-prem router ip address 1 on_prem_router_ip_address2 = "<8.8.8.8>" # on-prem router ip address 2 diff --git a/3-networks-dual-svpc/modules/base_shared_vpc/README.md b/3-networks-dual-svpc/modules/base_shared_vpc/README.md index e8c207265..83f5c5608 100644 --- a/3-networks-dual-svpc/modules/base_shared_vpc/README.md +++ b/3-networks-dual-svpc/modules/base_shared_vpc/README.md @@ -10,6 +10,7 @@ | default\_region2 | Default region 2 for subnets and Cloud Routers | `string` | n/a | yes | | 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 | +| dns\_hub\_project\_id | The DNS hub project ID | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | | 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 | diff --git a/3-networks-dual-svpc/modules/base_shared_vpc/dns.tf b/3-networks-dual-svpc/modules/base_shared_vpc/dns.tf index 039cbd0f1..0a6b62f48 100644 --- a/3-networks-dual-svpc/modules/base_shared_vpc/dns.tf +++ b/3-networks-dual-svpc/modules/base_shared_vpc/dns.tf @@ -14,28 +14,6 @@ * limitations under the License. */ -locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = local.parent_id -} - -/****************************************** - DNS Hub Project -*****************************************/ - -data "google_projects" "dns_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-dns-hub lifecycleState=ACTIVE" -} - -data "google_compute_network" "vpc_dns_hub" { - name = "vpc-c-dns-hub" - project = data.google_projects.dns_hub.projects[0].project_id -} - /****************************************** Default DNS Policy *****************************************/ @@ -53,6 +31,11 @@ resource "google_dns_policy" "default_policy" { /****************************************** Creates DNS Peering to DNS HUB *****************************************/ +data "google_compute_network" "vpc_dns_hub" { + name = "vpc-c-dns-hub" + project = var.dns_hub_project_id +} + module "peering_zone" { source = "terraform-google-modules/cloud-dns/google" version = "~> 3.1" diff --git a/3-networks-dual-svpc/modules/base_shared_vpc/variables.tf b/3-networks-dual-svpc/modules/base_shared_vpc/variables.tf index ba675a184..1c28e38ee 100644 --- a/3-networks-dual-svpc/modules/base_shared_vpc/variables.tf +++ b/3-networks-dual-svpc/modules/base_shared_vpc/variables.tf @@ -24,6 +24,11 @@ variable "project_id" { description = "Project ID for Private Shared VPC." } +variable "dns_hub_project_id" { + type = string + description = "The DNS hub project ID" +} + variable "environment_code" { type = string description = "A short form of the folder level resources (environment) within the Google Cloud organization." diff --git a/3-networks-dual-svpc/modules/dedicated_interconnect/README.md b/3-networks-dual-svpc/modules/dedicated_interconnect/README.md index f4924c200..803fa7662 100644 --- a/3-networks-dual-svpc/modules/dedicated_interconnect/README.md +++ b/3-networks-dual-svpc/modules/dedicated_interconnect/README.md @@ -19,8 +19,7 @@ This module implements the recommendation proposed in [Establishing 99.99% Avail |------|-------------|------|---------|:--------:| | cloud\_router\_labels | A map of suffixes for labelling vlans with four entries like "vlan\_1" => "suffix1" with keys from `vlan_1` to `vlan_4`. | `map(string)` | `{}` | no | | folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | +| interconnect\_project\_id | Interconnect project ID. | `string` | n/a | yes | | peer\_asn | Peer BGP Autonomous System Number (ASN). | `number` | n/a | yes | | peer\_name | Name of this BGP peer. The name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression [a-z]([-a-z0-9]\*[a-z0-9])? | `string` | n/a | yes | | region1 | First subnet region. The Dedicated Interconnect module only configures two regions. | `string` | n/a | yes | diff --git a/3-networks-dual-svpc/modules/dedicated_interconnect/main.tf b/3-networks-dual-svpc/modules/dedicated_interconnect/main.tf index 23d3118e3..0eb62bc83 100644 --- a/3-networks-dual-svpc/modules/dedicated_interconnect/main.tf +++ b/3-networks-dual-svpc/modules/dedicated_interconnect/main.tf @@ -15,21 +15,10 @@ */ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - interconnect_project_id = data.google_projects.interconnect_project.projects[0].project_id - suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") - suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") - suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") - suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") -} - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = local.parent_id -} - -data "google_projects" "interconnect_project" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-interconnect lifecycleState=ACTIVE" + suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") + suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") + suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") + suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") } module "interconnect_attachment1_region1" { @@ -37,7 +26,7 @@ module "interconnect_attachment1_region1" { version = "~> 2.0.0" name = "vl-${var.region1_interconnect1_location}-${var.vpc_name}-${var.region1}-${local.suffix1}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region1 router = var.region1_router1_name @@ -60,7 +49,7 @@ module "interconnect_attachment2_region1" { version = "~> 0.4.0" name = "vl-${var.region1_interconnect2_location}-${var.vpc_name}-${var.region1}-${local.suffix2}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region1 router = var.region1_router2_name @@ -83,7 +72,7 @@ module "interconnect_attachment1_region2" { version = "~> 0.4.0" name = "vl-${var.region2_interconnect1_location}-${var.vpc_name}-${var.region2}-${local.suffix3}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region2 router = var.region2_router1_name @@ -106,7 +95,7 @@ module "interconnect_attachment2_region2" { version = "~> 0.4.0" name = "vl-${var.region2_interconnect2_location}-${var.vpc_name}-${var.region2}-${local.suffix4}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region2 router = var.region2_router2_name diff --git a/3-networks-dual-svpc/modules/dedicated_interconnect/variables.tf b/3-networks-dual-svpc/modules/dedicated_interconnect/variables.tf index 4589e1660..74b21562c 100644 --- a/3-networks-dual-svpc/modules/dedicated_interconnect/variables.tf +++ b/3-networks-dual-svpc/modules/dedicated_interconnect/variables.tf @@ -14,15 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "interconnect_project_id" { type = string - description = "Organization ID" -} - -variable "parent_folder" { - description = "Optional - if using a folder for testing." - type = string - default = "" + description = "Interconnect project ID." } variable "vpc_name" { diff --git a/3-networks-dual-svpc/modules/partner_interconnect/README.md b/3-networks-dual-svpc/modules/partner_interconnect/README.md index e3e6583a4..16decf715 100644 --- a/3-networks-dual-svpc/modules/partner_interconnect/README.md +++ b/3-networks-dual-svpc/modules/partner_interconnect/README.md @@ -19,11 +19,9 @@ Without Hub and Spoke enabled VLAN attachments will be created in `prj-{p|n|d}-s | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| attachment\_project\_id | the Interconnect project ID. | `string` | n/a | yes | | cloud\_router\_labels | A map of suffixes for labelling vlans with four entries like "vlan\_1" => "suffix1" with keys from `vlan_1` to `vlan_4`. | `map(string)` | `{}` | no | -| environment | Environment in which to deploy the Partner Interconnect, must be 'common' if enable\_hub\_and\_spoke=true | `string` | `null` | no | | folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | | preactivate | Preactivate Partner Interconnect attachments, works only for level3 Partner Interconnect | `string` | `false` | no | | region1 | First subnet region. The Partner Interconnect module only configures two regions. | `string` | n/a | yes | | region1\_interconnect1\_location | Name of the interconnect location used in the creation of the Interconnect for the first location of region1 | `string` | n/a | yes | diff --git a/3-networks-dual-svpc/modules/partner_interconnect/main.tf b/3-networks-dual-svpc/modules/partner_interconnect/main.tf index e7b81a908..795695093 100644 --- a/3-networks-dual-svpc/modules/partner_interconnect/main.tf +++ b/3-networks-dual-svpc/modules/partner_interconnect/main.tf @@ -15,30 +15,15 @@ */ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") - suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") - suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") - suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") - - attachment_project_id = data.google_projects.attachment_project.projects[0].project_id - - app_label = "${var.vpc_type}-shared-vpc-host" - environment_label = var.environment -} - -data "google_active_folder" "environment" { - display_name = "${var.folder_prefix}-${var.environment}" - parent = local.parent_id -} - -data "google_projects" "attachment_project" { - filter = "parent.id:${split("/", data.google_active_folder.environment.name)[1]} labels.application_name=${local.app_label} labels.environment=${local.environment_label} lifecycleState=ACTIVE" + suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") + suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") + suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") + suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") } resource "google_compute_interconnect_attachment" "interconnect_attachment1_region1" { name = "vl-${var.region1_interconnect1_location}-${var.vpc_name}-${var.region1}-${local.suffix1}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region1 router = var.region1_router1_name @@ -49,7 +34,7 @@ resource "google_compute_interconnect_attachment" "interconnect_attachment1_regi resource "google_compute_interconnect_attachment" "interconnect_attachment2_region1" { name = "vl-${var.region1_interconnect2_location}-${var.vpc_name}-${var.region1}-${local.suffix2}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region1 router = var.region1_router2_name @@ -60,7 +45,7 @@ resource "google_compute_interconnect_attachment" "interconnect_attachment2_regi resource "google_compute_interconnect_attachment" "interconnect_attachment1_region2" { name = "vl-${var.region2_interconnect1_location}-${var.vpc_name}-${var.region2}-${local.suffix1}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region2 router = var.region2_router1_name @@ -71,7 +56,7 @@ resource "google_compute_interconnect_attachment" "interconnect_attachment1_regi resource "google_compute_interconnect_attachment" "interconnect_attachment2_region2" { name = "vl-${var.region2_interconnect2_location}-${var.vpc_name}-${var.region2}-${local.suffix2}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region2 router = var.region2_router2_name diff --git a/3-networks-dual-svpc/modules/partner_interconnect/variables.tf b/3-networks-dual-svpc/modules/partner_interconnect/variables.tf index de0cc447f..326fb26b3 100644 --- a/3-networks-dual-svpc/modules/partner_interconnect/variables.tf +++ b/3-networks-dual-svpc/modules/partner_interconnect/variables.tf @@ -14,15 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "attachment_project_id" { type = string - description = "Organization ID" -} - -variable "parent_folder" { - description = "Optional - if using a folder for testing." - type = string - default = "" + description = "the Interconnect project ID." } variable "vpc_name" { @@ -98,12 +92,6 @@ variable "preactivate" { default = false } -variable "environment" { - description = "Environment in which to deploy the Partner Interconnect, must be 'common' if enable_hub_and_spoke=true" - type = string - default = null -} - variable "vpc_type" { description = "To which Shared VPC Host attach the Partner Interconnect - base/restricted" type = string diff --git a/3-networks-dual-svpc/modules/restricted_shared_vpc/README.md b/3-networks-dual-svpc/modules/restricted_shared_vpc/README.md index 8d51f09e9..f79a75e91 100644 --- a/3-networks-dual-svpc/modules/restricted_shared_vpc/README.md +++ b/3-networks-dual-svpc/modules/restricted_shared_vpc/README.md @@ -11,6 +11,7 @@ | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | 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 | +| dns\_hub\_project\_id | The DNS hub project ID | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | | 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 | diff --git a/3-networks-dual-svpc/modules/restricted_shared_vpc/dns.tf b/3-networks-dual-svpc/modules/restricted_shared_vpc/dns.tf index dc90068a2..6ac8a6457 100644 --- a/3-networks-dual-svpc/modules/restricted_shared_vpc/dns.tf +++ b/3-networks-dual-svpc/modules/restricted_shared_vpc/dns.tf @@ -14,28 +14,6 @@ * limitations under the License. */ -locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = local.parent_id -} - -/****************************************** - DNS Hub Project -*****************************************/ - -data "google_projects" "dns_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-dns-hub lifecycleState=ACTIVE" -} - -data "google_compute_network" "vpc_dns_hub" { - name = "vpc-c-dns-hub" - project = data.google_projects.dns_hub.projects[0].project_id -} - /****************************************** Default DNS Policy *****************************************/ @@ -53,6 +31,11 @@ resource "google_dns_policy" "default_policy" { /****************************************** Creates DNS Peering to DNS HUB *****************************************/ +data "google_compute_network" "vpc_dns_hub" { + name = "vpc-c-dns-hub" + project = var.dns_hub_project_id +} + module "peering_zone" { source = "terraform-google-modules/cloud-dns/google" version = "~> 3.1" diff --git a/3-networks-dual-svpc/modules/restricted_shared_vpc/variables.tf b/3-networks-dual-svpc/modules/restricted_shared_vpc/variables.tf index 734359236..c5fce20c2 100644 --- a/3-networks-dual-svpc/modules/restricted_shared_vpc/variables.tf +++ b/3-networks-dual-svpc/modules/restricted_shared_vpc/variables.tf @@ -34,6 +34,11 @@ variable "project_number" { description = "Project number for Restricted Shared VPC. It is the project INSIDE the regular service perimeter." } +variable "dns_hub_project_id" { + type = string + description = "The DNS hub project ID" +} + variable "environment_code" { type = string description = "A short form of the folder level resources (environment) within the Google Cloud organization." diff --git a/3-networks-dual-svpc/modules/vpn-ha/README.md b/3-networks-dual-svpc/modules/vpn-ha/README.md index 311b772aa..ef51f800c 100755 --- a/3-networks-dual-svpc/modules/vpn-ha/README.md +++ b/3-networks-dual-svpc/modules/vpn-ha/README.md @@ -23,11 +23,10 @@ If you are not able to use Dedicated Interconnect or Partner Interconnect you ca | bgp\_peer\_asn | BGP ASN for cloud routes. | `number` | n/a | yes | | default\_region1 | Default region 1 for Cloud Routers | `string` | n/a | yes | | default\_region2 | Default region 2 for Cloud Routers | `string` | n/a | yes | -| environment | Environment for the VPN configuration. Valid options are development, non-production, production | `string` | n/a | yes | +| env\_secret\_project\_id | the environment secrets project ID | `string` | n/a | yes | | folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | | on\_prem\_router\_ip\_address1 | On-Prem Router IP address | `string` | n/a | yes | | on\_prem\_router\_ip\_address2 | On-Prem Router IP address | `string` | n/a | yes | -| org\_id | Organization ID | `string` | n/a | yes | | parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | | project\_id | VPC Project ID | `string` | n/a | yes | | region1\_router1\_name | Name of the Router 1 for Region 1 where the attachment resides. | `string` | n/a | yes | diff --git a/3-networks-dual-svpc/modules/vpn-ha/main.tf b/3-networks-dual-svpc/modules/vpn-ha/main.tf index f6fe3532f..77a48279d 100755 --- a/3-networks-dual-svpc/modules/vpn-ha/main.tf +++ b/3-networks-dual-svpc/modules/vpn-ha/main.tf @@ -19,23 +19,12 @@ *****************************************/ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - network_name = "vpc-${var.vpc_name}" - env_secret_project_id = data.google_projects.env_secrets.projects[0].project_id - psk_secret_data = chomp(data.google_secret_manager_secret_version.psk.secret_data) -} - -data "google_active_folder" "env" { - display_name = "${var.folder_prefix}-${var.environment}" - parent = local.parent_id -} - -data "google_projects" "env_secrets" { - filter = "parent.id:${split("/", data.google_active_folder.env.name)[1]} labels.application_name=env-secrets labels.environment=${var.environment} lifecycleState=ACTIVE" + network_name = "vpc-${var.vpc_name}" + psk_secret_data = chomp(data.google_secret_manager_secret_version.psk.secret_data) } data "google_secret_manager_secret_version" "psk" { - project = local.env_secret_project_id + project = var.env_secret_project_id secret = var.vpn_psk_secret_name } diff --git a/3-networks-dual-svpc/modules/vpn-ha/variables.tf b/3-networks-dual-svpc/modules/vpn-ha/variables.tf index 9cef8fc6e..b7ec1900b 100644 --- a/3-networks-dual-svpc/modules/vpn-ha/variables.tf +++ b/3-networks-dual-svpc/modules/vpn-ha/variables.tf @@ -19,6 +19,11 @@ variable "project_id" { description = "VPC Project ID" } +variable "env_secret_project_id" { + type = string + description = "the environment secrets project ID" +} + variable "default_region1" { type = string description = "Default region 1 for Cloud Routers" @@ -29,16 +34,6 @@ variable "default_region2" { description = "Default region 2 for Cloud Routers" } -variable "environment" { - type = string - description = "Environment for the VPN configuration. Valid options are development, non-production, production" -} - -variable "org_id" { - type = string - description = "Organization ID" -} - variable "vpn_psk_secret_name" { type = string description = "The name of the secret to retrieve from secret manager. This will be retrieved from the environment secrets project." diff --git a/3-networks-hub-and-spoke/common.auto.example.tfvars b/3-networks-hub-and-spoke/common.auto.example.tfvars index ce00f5219..fad68457d 100644 --- a/3-networks-hub-and-spoke/common.auto.example.tfvars +++ b/3-networks-hub-and-spoke/common.auto.example.tfvars @@ -14,15 +14,11 @@ * limitations under the License. */ -org_id = "000000000000" - terraform_service_account = "terraform-net-sa@prj-b-seed-2334.iam.gserviceaccount.com" // The DNS name of peering managed zone. Must end with a period. domain = "example.com." -// Optional - for an organization with existing projects or for development/validation. -// Must be the same value used in previous steps. -//parent_folder = "000000000000" +backend_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 bd347e54e..80162d5fd 100644 --- a/3-networks-hub-and-spoke/envs/development/README.md +++ b/3-networks-hub-and-spoke/envs/development/README.md @@ -16,17 +16,16 @@ The purpose of this step is to set up base and restricted shared VPCs with defau | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `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 | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | terraform\_service\_account | Service account email of the account to be added to the VPC-SC perimeter. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | base\_host\_project\_id | The base host project ID | | base\_network\_name | The name of the VPC being created | | base\_network\_self\_link | The URI of the VPC 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 ba63306b8..45d465106 100644 --- a/3-networks-hub-and-spoke/envs/development/main.tf +++ b/3-networks-hub-and-spoke/envs/development/main.tf @@ -66,13 +66,11 @@ module "base_env" { env = local.env environment_code = local.environment_code - org_id = var.org_id access_context_manager_policy_id = var.access_context_manager_policy_id members = ["serviceAccount:${var.terraform_service_account}"] default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - parent_folder = var.parent_folder enable_partner_interconnect = false enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity base_private_service_cidr = local.base_private_service_cidr @@ -81,5 +79,5 @@ module "base_env" { restricted_private_service_cidr = local.restricted_private_service_cidr restricted_subnet_primary_ranges = local.restricted_subnet_primary_ranges restricted_subnet_secondary_ranges = local.restricted_subnet_secondary_ranges - + backend_bucket = var.backend_bucket } diff --git a/3-networks-hub-and-spoke/envs/development/outputs.tf b/3-networks-hub-and-spoke/envs/development/outputs.tf index 673db1adf..3adb70885 100644 --- a/3-networks-hub-and-spoke/envs/development/outputs.tf +++ b/3-networks-hub-and-spoke/envs/development/outputs.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +output "access_context_manager_policy_id" { + description = "Access Context Manager Policy ID." + value = var.access_context_manager_policy_id +} + /********************* Restricted Outputs *********************/ diff --git a/3-networks-hub-and-spoke/envs/development/variables.tf b/3-networks-hub-and-spoke/envs/development/variables.tf index 03961c6e9..60920e064 100644 --- a/3-networks-hub-and-spoke/envs/development/variables.tf +++ b/3-networks-hub-and-spoke/envs/development/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "access_context_manager_policy_id" { @@ -34,18 +34,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - variable "enable_hub_and_spoke_transitivity" { description = "Enable transitivity via gateway VMs on Hub-and-Spoke architecture." type = bool diff --git a/3-networks-hub-and-spoke/envs/non-production/README.md b/3-networks-hub-and-spoke/envs/non-production/README.md index 57eccabef..0c7a4bf4b 100644 --- a/3-networks-hub-and-spoke/envs/non-production/README.md +++ b/3-networks-hub-and-spoke/envs/non-production/README.md @@ -16,17 +16,16 @@ The purpose of this step is to set up base and restricted shared VPCs with defau | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `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 | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | terraform\_service\_account | Service account email of the account to be added to the VPC-SC perimeter. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | base\_host\_project\_id | The base host project ID | | base\_network\_name | The name of the VPC being created | | base\_network\_self\_link | The URI of the VPC being created | diff --git a/3-networks-hub-and-spoke/envs/non-production/main.tf b/3-networks-hub-and-spoke/envs/non-production/main.tf index 538a1baa3..1835f61a6 100644 --- a/3-networks-hub-and-spoke/envs/non-production/main.tf +++ b/3-networks-hub-and-spoke/envs/non-production/main.tf @@ -66,13 +66,11 @@ module "base_env" { env = local.env environment_code = local.environment_code - org_id = var.org_id access_context_manager_policy_id = var.access_context_manager_policy_id members = ["serviceAccount:${var.terraform_service_account}"] default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - parent_folder = var.parent_folder enable_partner_interconnect = false enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity base_private_service_cidr = local.base_private_service_cidr @@ -81,4 +79,5 @@ module "base_env" { restricted_private_service_cidr = local.restricted_private_service_cidr restricted_subnet_primary_ranges = local.restricted_subnet_primary_ranges restricted_subnet_secondary_ranges = local.restricted_subnet_secondary_ranges + backend_bucket = var.backend_bucket } diff --git a/3-networks-hub-and-spoke/envs/non-production/outputs.tf b/3-networks-hub-and-spoke/envs/non-production/outputs.tf index 673db1adf..3adb70885 100644 --- a/3-networks-hub-and-spoke/envs/non-production/outputs.tf +++ b/3-networks-hub-and-spoke/envs/non-production/outputs.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +output "access_context_manager_policy_id" { + description = "Access Context Manager Policy ID." + value = var.access_context_manager_policy_id +} + /********************* Restricted Outputs *********************/ diff --git a/3-networks-hub-and-spoke/envs/non-production/variables.tf b/3-networks-hub-and-spoke/envs/non-production/variables.tf index 03961c6e9..60920e064 100644 --- a/3-networks-hub-and-spoke/envs/non-production/variables.tf +++ b/3-networks-hub-and-spoke/envs/non-production/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "access_context_manager_policy_id" { @@ -34,18 +34,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - variable "enable_hub_and_spoke_transitivity" { description = "Enable transitivity via gateway VMs on Hub-and-Spoke architecture." type = bool diff --git a/3-networks-hub-and-spoke/envs/production/README.md b/3-networks-hub-and-spoke/envs/production/README.md index 5832b170d..501388994 100644 --- a/3-networks-hub-and-spoke/envs/production/README.md +++ b/3-networks-hub-and-spoke/envs/production/README.md @@ -16,17 +16,16 @@ The purpose of this step is to set up base and restricted shared VPCs with defau | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `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 | | enable\_hub\_and\_spoke\_transitivity | Enable transitivity via gateway VMs on Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | terraform\_service\_account | Service account email of the account to be added to the VPC-SC perimeter. | `string` | n/a | yes | ## Outputs | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | base\_host\_project\_id | The base host project ID | | base\_network\_name | The name of the VPC being created | | base\_network\_self\_link | The URI of the VPC 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 58dcd8e24..a68d59405 100644 --- a/3-networks-hub-and-spoke/envs/production/main.tf +++ b/3-networks-hub-and-spoke/envs/production/main.tf @@ -66,13 +66,11 @@ module "base_env" { env = local.env environment_code = local.environment_code - org_id = var.org_id access_context_manager_policy_id = var.access_context_manager_policy_id members = ["serviceAccount:${var.terraform_service_account}"] default_region1 = local.default_region1 default_region2 = local.default_region2 domain = var.domain - parent_folder = var.parent_folder enable_partner_interconnect = false enable_hub_and_spoke_transitivity = var.enable_hub_and_spoke_transitivity base_private_service_cidr = local.base_private_service_cidr @@ -81,4 +79,5 @@ module "base_env" { restricted_private_service_cidr = local.restricted_private_service_cidr restricted_subnet_primary_ranges = local.restricted_subnet_primary_ranges restricted_subnet_secondary_ranges = local.restricted_subnet_secondary_ranges + backend_bucket = var.backend_bucket } diff --git a/3-networks-hub-and-spoke/envs/production/outputs.tf b/3-networks-hub-and-spoke/envs/production/outputs.tf index 673db1adf..3adb70885 100644 --- a/3-networks-hub-and-spoke/envs/production/outputs.tf +++ b/3-networks-hub-and-spoke/envs/production/outputs.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +output "access_context_manager_policy_id" { + description = "Access Context Manager Policy ID." + value = var.access_context_manager_policy_id +} + /********************* Restricted Outputs *********************/ diff --git a/3-networks-hub-and-spoke/envs/production/variables.tf b/3-networks-hub-and-spoke/envs/production/variables.tf index 03961c6e9..60920e064 100644 --- a/3-networks-hub-and-spoke/envs/production/variables.tf +++ b/3-networks-hub-and-spoke/envs/production/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "access_context_manager_policy_id" { @@ -34,18 +34,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - variable "enable_hub_and_spoke_transitivity" { description = "Enable transitivity via gateway VMs on Hub-and-Spoke architecture." type = bool diff --git a/3-networks-hub-and-spoke/envs/shared/README.md b/3-networks-hub-and-spoke/envs/shared/README.md index ec681443f..53aea7289 100644 --- a/3-networks-hub-and-spoke/envs/shared/README.md +++ b/3-networks-hub-and-spoke/envs/shared/README.md @@ -13,6 +13,7 @@ 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | base\_hub\_dns\_enable\_inbound\_forwarding | Toggle inbound query forwarding for Base Hub VPC DNS. | `bool` | `true` | no | | base\_hub\_dns\_enable\_logging | Toggle DNS logging for Base Hub VPC DNS. | `bool` | `true` | no | | base\_hub\_firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls in Base Hub VPC. | `bool` | `true` | no | @@ -27,9 +28,6 @@ The purpose of this step is to set up the global [DNS Hub](https://cloud.google. | 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 | | firewall\_policies\_enable\_logging | Toggle hierarchical firewall logging. | `bool` | `true` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | preactivate\_partner\_interconnect | Preactivate Partner Interconnect VLAN attachment in the environment. | `bool` | `false` | no | | restricted\_hub\_dns\_enable\_inbound\_forwarding | Toggle inbound query forwarding for Restricted Hub VPC DNS. | `bool` | `true` | no | | restricted\_hub\_dns\_enable\_logging | Toggle DNS logging for Restricted Hub VPC DNS. | `bool` | `true` | no | diff --git a/3-networks-hub-and-spoke/envs/shared/dns-hub.tf b/3-networks-hub-and-spoke/envs/shared/dns-hub.tf index 848cfab11..36484a1b2 100644 --- a/3-networks-hub-and-spoke/envs/shared/dns-hub.tf +++ b/3-networks-hub-and-spoke/envs/shared/dns-hub.tf @@ -14,39 +14,6 @@ * limitations under the License. */ -locals { - dns_hub_project_id = data.google_projects.dns_hub.projects[0].project_id -} - -data "google_active_folder" "bootstrap" { - display_name = "${var.folder_prefix}-bootstrap" - parent = local.parent_id -} - -data "google_active_folder" "development" { - display_name = "${var.folder_prefix}-development" - parent = local.parent_id -} - -data "google_active_folder" "production" { - display_name = "${var.folder_prefix}-production" - parent = local.parent_id -} - -data "google_active_folder" "non-production" { - display_name = "${var.folder_prefix}-non-production" - parent = local.parent_id -} - -/****************************************** - DNS Hub Project -*****************************************/ - -data "google_projects" "dns_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-dns-hub lifecycleState=ACTIVE" -} - - /****************************************** DNS Hub VPC *****************************************/ diff --git a/3-networks-hub-and-spoke/envs/shared/hierarchical_firewall.tf b/3-networks-hub-and-spoke/envs/shared/hierarchical_firewall.tf index db9202fb8..d924ff582 100644 --- a/3-networks-hub-and-spoke/envs/shared/hierarchical_firewall.tf +++ b/3-networks-hub-and-spoke/envs/shared/hierarchical_firewall.tf @@ -16,14 +16,14 @@ module "hierarchical_firewall_policy" { source = "../../modules/hierarchical_firewall_policy/" - parent = data.google_active_folder.common.name + parent = local.common_folder_name name = "common-firewall-rules" associations = [ - data.google_active_folder.common.name, - data.google_active_folder.bootstrap.name, - data.google_active_folder.development.name, - data.google_active_folder.production.name, - data.google_active_folder.non-production.name, + local.common_folder_name, + local.bootstrap_folder_name, + local.development_folder_name, + local.production_folder_name, + local.non_production_folder_name, ] rules = { delegate-rfc1918-ingress = { diff --git a/3-networks-hub-and-spoke/envs/shared/interconnect.tf.example b/3-networks-hub-and-spoke/envs/shared/interconnect.tf.example index c412743a9..906ce70cb 100644 --- a/3-networks-hub-and-spoke/envs/shared/interconnect.tf.example +++ b/3-networks-hub-and-spoke/envs/shared/interconnect.tf.example @@ -17,9 +17,8 @@ module "dns_hub_interconnect" { source = "../../modules/dedicated_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "c-dns-hub" + vpc_name = "c-dns-hub" + interconnect_project_id = local.interconnect_project_id region1 = local.default_region1 region1_router1_name = module.dns_hub_region1_router1.router.name diff --git a/3-networks-hub-and-spoke/envs/shared/main.tf b/3-networks-hub-and-spoke/envs/shared/main.tf index 7636dc61d..34b2dd6bd 100644 --- a/3-networks-hub-and-spoke/envs/shared/main.tf +++ b/3-networks-hub-and-spoke/envs/shared/main.tf @@ -15,15 +15,71 @@ */ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - env = "common" - environment_code = "c" - bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" - default_region1 = "us-west1" - default_region2 = "us-central1" + env = "common" + environment_code = "c" + bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" + default_region1 = "us-west1" + default_region2 = "us-central1" + dns_hub_project_id = data.terraform_remote_state.org.outputs.dns_hub_project_id + interconnect_project_id = data.terraform_remote_state.org.outputs.interconnect_project_id + parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix + parent_id = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + bootstrap_folder_name = data.terraform_remote_state.bootstrap.outputs.common_config.bootstrap_folder_name + common_folder_name = data.terraform_remote_state.org.outputs.common_folder_name + development_folder_name = data.terraform_remote_state.env_development.outputs.env_folder + non_production_folder_name = data.terraform_remote_state.env_non_production.outputs.env_folder + production_folder_name = data.terraform_remote_state.env_production.outputs.env_folder + base_net_hub_project_id = data.terraform_remote_state.org.outputs.base_net_hub_project_id + restricted_net_hub_project_id = data.terraform_remote_state.org.outputs.restricted_net_hub_project_id + restricted_net_hub_project_number = data.terraform_remote_state.org.outputs.restricted_net_hub_project_number } -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-${local.env}" - parent = local.parent_id +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } +} + +data "terraform_remote_state" "org" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/org/state" + } +} + +data "terraform_remote_state" "env_development" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/development" + } +} + +data "terraform_remote_state" "env_non_production" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/non-production" + } +} + +data "terraform_remote_state" "env_production" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/production" + } } 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 7e730cfb3..4f67c351b 100644 --- a/3-networks-hub-and-spoke/envs/shared/net-hubs.tf +++ b/3-networks-hub-and-spoke/envs/shared/net-hubs.tf @@ -15,9 +15,6 @@ */ locals { - base_net_hub_project_id = data.google_projects.base_net_hub.projects[0].project_id - restricted_net_hub_project_id = data.google_projects.restricted_net_hub.projects[0].project_id - restricted_net_hub_project_number = data.google_projects.restricted_net_hub.projects[0].number /* * Base network ranges */ @@ -34,22 +31,6 @@ locals { } } -/****************************************** - Base Network Hub Project -*****************************************/ - -data "google_projects" "base_net_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-base-net-hub lifecycleState=ACTIVE" -} - -/****************************************** - Restricted Network Hub Project -*****************************************/ - -data "google_projects" "restricted_net_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-restricted-net-hub lifecycleState=ACTIVE" -} - /****************************************** Base Network VPC *****************************************/ @@ -57,9 +38,9 @@ data "google_projects" "restricted_net_hub" { module "base_shared_vpc" { source = "../../modules/base_shared_vpc" project_id = local.base_net_hub_project_id + dns_hub_project_id = local.dns_hub_project_id environment_code = local.environment_code - org_id = var.org_id - parent_folder = var.parent_folder + org_id = local.org_id bgp_asn_subnet = local.bgp_asn_number default_region1 = local.default_region1 default_region2 = local.default_region2 @@ -72,7 +53,6 @@ module "base_shared_vpc" { nat_num_addresses_region1 = var.base_hub_nat_num_addresses_region1 nat_num_addresses_region2 = var.base_hub_nat_num_addresses_region2 windows_activation_enabled = var.base_hub_windows_activation_enabled - folder_prefix = var.folder_prefix mode = "hub" subnets = [ @@ -106,12 +86,12 @@ module "restricted_shared_vpc" { source = "../../modules/restricted_shared_vpc" project_id = local.restricted_net_hub_project_id project_number = local.restricted_net_hub_project_number + dns_hub_project_id = local.dns_hub_project_id environment_code = local.environment_code access_context_manager_policy_id = var.access_context_manager_policy_id restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] members = ["serviceAccount:${var.terraform_service_account}"] - org_id = var.org_id - parent_folder = var.parent_folder + org_id = local.org_id bgp_asn_subnet = local.bgp_asn_number default_region1 = local.default_region1 default_region2 = local.default_region2 @@ -123,7 +103,6 @@ module "restricted_shared_vpc" { nat_bgp_asn = var.restricted_hub_nat_bgp_asn nat_num_addresses_region1 = var.restricted_hub_nat_num_addresses_region1 nat_num_addresses_region2 = var.restricted_hub_nat_num_addresses_region2 - folder_prefix = var.folder_prefix windows_activation_enabled = var.restricted_hub_windows_activation_enabled mode = "hub" diff --git a/3-networks-hub-and-spoke/envs/shared/partner_interconnect.tf.example b/3-networks-hub-and-spoke/envs/shared/partner_interconnect.tf.example index 2b4a07a20..49e342901 100644 --- a/3-networks-hub-and-spoke/envs/shared/partner_interconnect.tf.example +++ b/3-networks-hub-and-spoke/envs/shared/partner_interconnect.tf.example @@ -15,14 +15,12 @@ */ module "shared_restricted_interconnect" { - source = "../../modules/partner_interconnect" + source = "../../modules/partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${local.environment_code}-shared-restricted" - environment = local.env - vpc_type = "restricted" - preactivate = var.preactivate_partner_interconnect + attachment_project_id = local.restricted_net_hub_project_id + vpc_name = "${local.environment_code}-shared-restricted" + vpc_type = "restricted" + preactivate = var.preactivate_partner_interconnect region1 = local.default_region1 region1_router1_name = module.restricted_shared_vpc[0].region1_router1.router.name @@ -36,8 +34,6 @@ module "shared_restricted_interconnect" { region2_router2_name = module.restricted_shared_vpc[0].region2_router2.router.name region2_interconnect2_location = "lax-zone1-403" - folder_prefix = var.folder_prefix - cloud_router_labels = { vlan_1 = "cr5", vlan_2 = "cr6", @@ -47,14 +43,12 @@ module "shared_restricted_interconnect" { } module "shared_base_interconnect" { - source = "../../modules/partner_interconnect" + source = "../../modules/partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${local.environment_code}-shared-base" - environment = local.env - vpc_type = "base" - preactivate = var.preactivate_partner_interconnect + attachment_project_id = local.base_net_hub_project_id + vpc_name = "${local.environment_code}-shared-base" + vpc_type = "base" + preactivate = var.preactivate_partner_interconnect region1 = local.default_region1 region1_router1_name = module.base_shared_vpc[0].region1_router1.router.name @@ -68,8 +62,6 @@ module "shared_base_interconnect" { region2_router2_name = module.base_shared_vpc[0].region2_router2.router.name region2_interconnect2_location = "lax-zone1-403" - folder_prefix = var.folder_prefix - cloud_router_labels = { vlan_1 = "cr1", vlan_2 = "cr2", diff --git a/3-networks-hub-and-spoke/envs/shared/variables.tf b/3-networks-hub-and-spoke/envs/shared/variables.tf index 1a012e768..e376dd703 100644 --- a/3-networks-hub-and-spoke/envs/shared/variables.tf +++ b/3-networks-hub-and-spoke/envs/shared/variables.tf @@ -14,9 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - description = "Organization ID" } variable "terraform_service_account" { @@ -57,18 +57,6 @@ variable "target_name_server_addresses" { type = list(string) } -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - variable "base_hub_windows_activation_enabled" { type = bool description = "Enable Windows license activation for Windows workloads in Base Hub" 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 d5f0bd633..a7786115e 100644 --- a/3-networks-hub-and-spoke/modules/base_env/README.md +++ b/3-networks-hub-and-spoke/modules/base_env/README.md @@ -4,6 +4,7 @@ | 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 | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | base\_private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Base Shared Vpc. | `string` | n/a | yes | | base\_subnet\_primary\_ranges | The base subnet primary IPTs ranges to the Base Shared Vpc. | `map(string)` | n/a | yes | | base\_subnet\_secondary\_ranges | The base subnet secondary IPTs ranges to the Base Shared Vpc. | `map(list(map(string)))` | n/a | yes | @@ -14,10 +15,7 @@ | 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 | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | | members | An allowed list of members (users, service accounts)to be include in the VPC-SC 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 | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | restricted\_private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services in the Restricted Shared Vpc. | `string` | n/a | yes | | restricted\_subnet\_primary\_ranges | The base subnet primary IPTs ranges to the Restricted Shared Vpc. | `map(string)` | n/a | yes | | restricted\_subnet\_secondary\_ranges | The base subnet secondary IPTs ranges to the Restricted Shared Vpc | `map(list(map(string)))` | n/a | yes | diff --git a/3-networks-hub-and-spoke/modules/base_env/interconnect.tf.example b/3-networks-hub-and-spoke/modules/base_env/interconnect.tf.example index 9c59be696..68fe4dd8d 100644 --- a/3-networks-hub-and-spoke/modules/base_env/interconnect.tf.example +++ b/3-networks-hub-and-spoke/modules/base_env/interconnect.tf.example @@ -17,9 +17,7 @@ module "shared_restricted_interconnect" { source = "../dedicated_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-restricted" + vpc_name = "${var.environment_code}-shared-restricted" region1 = var.default_region1 region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name @@ -59,9 +57,8 @@ module "shared_restricted_interconnect" { module "shared_base_interconnect" { source = "../dedicated_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-base" + vpc_name = "${var.environment_code}-shared-base" + interconnect_project_id = local.interconnect_project_id region1 = var.default_region1 region1_router1_name = module.base_shared_vpc.region1_router1.router.name 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 47fd62967..aca6f124c 100644 --- a/3-networks-hub-and-spoke/modules/base_env/main.tf +++ b/3-networks-hub-and-spoke/modules/base_env/main.tf @@ -15,12 +15,23 @@ */ locals { - restricted_project_id = data.google_projects.restricted_host_project.projects[0].project_id - restricted_project_number = data.google_project.restricted_host_project.number - base_project_id = data.google_projects.base_host_project.projects[0].project_id - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" - enable_transitivity = var.enable_hub_and_spoke_transitivity + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder + parent_id = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix + restricted_project_id = data.terraform_remote_state.environments_env.outputs.restricted_shared_vpc_project_id + restricted_project_number = data.terraform_remote_state.environments_env.outputs.restricted_shared_vpc_project_number + base_project_id = data.terraform_remote_state.environments_env.outputs.base_shared_vpc_project_id + env_secret_project_id = data.terraform_remote_state.environments_env.outputs.env_secrets_project_id + interconnect_project_id = data.terraform_remote_state.org.outputs.interconnect_project_id + dns_hub_project_id = data.terraform_remote_state.org.outputs.dns_hub_project_id + base_net_hub_project_id = data.terraform_remote_state.org.outputs.base_net_hub_project_id + restricted_net_hub_project_id = data.terraform_remote_state.org.outputs.restricted_net_hub_project_id + restricted_net_hub_project_number = data.terraform_remote_state.org.outputs.restricted_net_hub_project_number + bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" + enable_transitivity = var.enable_hub_and_spoke_transitivity /* * Base network ranges */ @@ -33,46 +44,63 @@ locals { restricted_hub_subnet_ranges = ["10.8.0.0/24", "10.9.0.0/24"] } -data "google_active_folder" "env" { - display_name = "${var.folder_prefix}-${var.env}" - parent = local.parent_id +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } } -/****************************************** - VPC Host Projects -*****************************************/ +data "terraform_remote_state" "org" { + backend = "gcs" -data "google_projects" "restricted_host_project" { - filter = "parent.id:${split("/", data.google_active_folder.env.name)[1]} labels.application_name=restricted-shared-vpc-host labels.environment=${var.env} lifecycleState=ACTIVE" + config = { + bucket = var.backend_bucket + prefix = "terraform/org/state" + } } -data "google_project" "restricted_host_project" { - project_id = data.google_projects.restricted_host_project.projects[0].project_id +data "terraform_remote_state" "network_shared" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/networks/envs/shared" + } } -data "google_projects" "base_host_project" { - filter = "parent.id:${split("/", data.google_active_folder.env.name)[1]} labels.application_name=base-shared-vpc-host labels.environment=${var.env} lifecycleState=ACTIVE" +data "terraform_remote_state" "environments_env" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/${var.env}" + } } /****************************************** Restricted shared VPC *****************************************/ module "restricted_shared_vpc" { - source = "../restricted_shared_vpc" - project_id = local.restricted_project_id - project_number = local.restricted_project_number - environment_code = var.environment_code - access_context_manager_policy_id = var.access_context_manager_policy_id - restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] - members = var.members - private_service_cidr = var.restricted_private_service_cidr - org_id = var.org_id - parent_folder = var.parent_folder - bgp_asn_subnet = local.bgp_asn_number - default_region1 = var.default_region1 - default_region2 = var.default_region2 - domain = var.domain - mode = "spoke" + source = "../restricted_shared_vpc" + project_id = local.restricted_project_id + project_number = local.restricted_project_number + dns_hub_project_id = local.dns_hub_project_id + restricted_net_hub_project_id = local.restricted_net_hub_project_id + restricted_net_hub_project_number = local.restricted_net_hub_project_number + environment_code = var.environment_code + access_context_manager_policy_id = var.access_context_manager_policy_id + restricted_services = ["bigquery.googleapis.com", "storage.googleapis.com"] + members = var.members + private_service_cidr = var.restricted_private_service_cidr + org_id = local.org_id + bgp_asn_subnet = local.bgp_asn_number + default_region1 = var.default_region1 + default_region2 = var.default_region2 + domain = var.domain + mode = "spoke" subnets = [ { @@ -104,17 +132,18 @@ module "restricted_shared_vpc" { *****************************************/ module "base_shared_vpc" { - source = "../base_shared_vpc" - project_id = local.base_project_id - environment_code = var.environment_code - private_service_cidr = var.base_private_service_cidr - org_id = var.org_id - parent_folder = var.parent_folder - default_region1 = var.default_region1 - default_region2 = var.default_region2 - domain = var.domain - bgp_asn_subnet = local.bgp_asn_number - mode = "spoke" + source = "../base_shared_vpc" + project_id = local.base_project_id + dns_hub_project_id = local.dns_hub_project_id + base_net_hub_project_id = local.base_net_hub_project_id + environment_code = var.environment_code + private_service_cidr = var.base_private_service_cidr + org_id = local.org_id + default_region1 = var.default_region1 + default_region2 = var.default_region2 + domain = var.domain + bgp_asn_subnet = local.bgp_asn_number + mode = "spoke" subnets = [ { diff --git a/3-networks-hub-and-spoke/modules/base_env/partner_interconnect.tf.example b/3-networks-hub-and-spoke/modules/base_env/partner_interconnect.tf.example index 2d531cbee..8b86d9567 100644 --- a/3-networks-hub-and-spoke/modules/base_env/partner_interconnect.tf.example +++ b/3-networks-hub-and-spoke/modules/base_env/partner_interconnect.tf.example @@ -15,14 +15,12 @@ */ module "shared_restricted_interconnect" { - source = "../partner_interconnect" + source = "../partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-restricted" - environment = var.env - vpc_type = "restricted" - preactivate = true + attachment_project_id = local.restricted_net_hub_project_id + vpc_name = "${var.environment_code}-shared-restricted" + vpc_type = "restricted" + preactivate = true region1 = var.default_region1 region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name @@ -45,14 +43,12 @@ module "shared_restricted_interconnect" { } module "shared_base_interconnect" { - source = "../partner_interconnect" + source = "../partner_interconnect" - org_id = var.org_id - parent_folder = var.parent_folder - vpc_name = "${var.environment_code}-shared-base" - environment = var.env - vpc_type = "base" - preactivate = true + attachment_project_id = local.base_net_hub_project_id + vpc_name = "${var.environment_code}-shared-base" + vpc_type = "base" + preactivate = true region1 = var.default_region1 region1_router1_name = module.base_shared_vpc.region1_router1.router.name 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 ed6359254..d56a91758 100644 --- a/3-networks-hub-and-spoke/modules/base_env/variables.tf +++ b/3-networks-hub-and-spoke/modules/base_env/variables.tf @@ -14,6 +14,11 @@ * limitations under the License. */ +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." + type = string +} + variable "env" { description = "The environment to prepare (ex. development)" type = string @@ -24,11 +29,6 @@ variable "environment_code" { description = "A short form of the folder level resources (environment) within the Google Cloud organization (ex. d)." } -variable "org_id" { - type = string - description = "Organization ID" -} - 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)\"`." @@ -49,18 +49,6 @@ variable "domain" { description = "The DNS name of peering managed zone, for instance 'example.com.'. Must end with a period." } -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - variable "enable_partner_interconnect" { description = "Enable Partner Interconnect in the environment." type = bool diff --git a/3-networks-hub-and-spoke/modules/base_env/vpn.tf.example b/3-networks-hub-and-spoke/modules/base_env/vpn.tf.example index f04d89f4f..9b165ec4d 100644 --- a/3-networks-hub-and-spoke/modules/base_env/vpn.tf.example +++ b/3-networks-hub-and-spoke/modules/base_env/vpn.tf.example @@ -17,19 +17,16 @@ module "shared_base_vpn" { source = "../vpn-ha" - project_id = local.base_project_id - default_region1 = var.default_region1 - default_region2 = var.default_region2 - vpc_name = "${var.environment_code}-shared-base" - region1_router1_name = module.base_shared_vpc.region1_router1.router.name - region1_router2_name = module.base_shared_vpc.region1_router2.router.name - region2_router1_name = module.base_shared_vpc.region2_router1.router.name - region2_router2_name = module.base_shared_vpc.region2_router2.router.name - environment = var.env - parent_folder = var.parent_folder - org_id = var.org_id - vpn_psk_secret_name = "" - folder_prefix = var.folder_prefix + project_id = local.base_project_id + env_secret_project_id = local.env_secret_project_id + default_region1 = var.default_region1 + default_region2 = var.default_region2 + vpc_name = "${var.environment_code}-shared-base" + region1_router1_name = module.base_shared_vpc.region1_router1.router.name + region1_router2_name = module.base_shared_vpc.region1_router2.router.name + region2_router1_name = module.base_shared_vpc.region2_router1.router.name + region2_router2_name = module.base_shared_vpc.region2_router2.router.name + vpn_psk_secret_name = "" on_prem_router_ip_address1 = "<8.8.8.8>" # on-prem router ip address 1 on_prem_router_ip_address2 = "<8.8.8.8>" # on-prem router ip address 2 @@ -63,18 +60,16 @@ module "shared_base_vpn" { module "shared_restricted_vpn" { source = "../vpn-ha" - project_id = local.restricted_project_id - default_region1 = var.default_region1 - default_region2 = var.default_region2 - vpc_name = "${var.environment_code}-shared-restricted" - region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name - region1_router2_name = module.restricted_shared_vpc.region1_router2.router.name - region2_router1_name = module.restricted_shared_vpc.region2_router1.router.name - region2_router2_name = module.restricted_shared_vpc.region2_router2.router.name - environment = var.env - parent_folder = var.parent_folder - org_id = var.org_id - vpn_psk_secret_name = "" + project_id = local.restricted_project_id + env_secret_project_id = local.env_secret_project_id + default_region1 = var.default_region1 + default_region2 = var.default_region2 + vpc_name = "${var.environment_code}-shared-restricted" + region1_router1_name = module.restricted_shared_vpc.region1_router1.router.name + region1_router2_name = module.restricted_shared_vpc.region1_router2.router.name + region2_router1_name = module.restricted_shared_vpc.region2_router1.router.name + region2_router2_name = module.restricted_shared_vpc.region2_router2.router.name + vpn_psk_secret_name = "" on_prem_router_ip_address1 = "<8.8.8.8>" # on-prem router ip address 1 on_prem_router_ip_address2 = "<8.8.8.8>" # on-prem router ip address 2 diff --git a/3-networks-hub-and-spoke/modules/base_shared_vpc/README.md b/3-networks-hub-and-spoke/modules/base_shared_vpc/README.md index 14155fb65..e2bd1b315 100644 --- a/3-networks-hub-and-spoke/modules/base_shared_vpc/README.md +++ b/3-networks-hub-and-spoke/modules/base_shared_vpc/README.md @@ -5,15 +5,16 @@ |------|-------------|------|---------|:--------:| | allow\_all\_egress\_ranges | List of network ranges to which all egress traffic will be allowed | `any` | `null` | no | | allow\_all\_ingress\_ranges | List of network ranges from which all ingress traffic will be allowed | `any` | `null` | no | +| base\_net\_hub\_project\_id | The base net hub project ID | `string` | `""` | no | | bgp\_asn\_subnet | BGP ASN for Subnets cloud routers. | `number` | n/a | yes | | default\_region1 | Default region 1 for subnets and Cloud Routers | `string` | n/a | yes | | default\_region2 | Default region 2 for subnets and Cloud Routers | `string` | n/a | yes | | 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 | +| dns\_hub\_project\_id | The DNS hub project ID | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | | 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 | -| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | | 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 first NAT cloud routes. | `number` | `64514` | no | | nat\_enabled | Toggle creation of NAT cloud router. | `bool` | `false` | no | @@ -21,7 +22,6 @@ | nat\_num\_addresses\_region1 | Number of external IPs to reserve for first Cloud NAT. | `number` | `2` | no | | nat\_num\_addresses\_region2 | Number of external IPs to reserve for second Cloud NAT. | `number` | `2` | no | | org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | | private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services. | `string` | `null` | no | | project\_id | Project ID for Private Shared VPC. | `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 | diff --git a/3-networks-hub-and-spoke/modules/base_shared_vpc/dns.tf b/3-networks-hub-and-spoke/modules/base_shared_vpc/dns.tf index 63689fe60..83f3a051c 100644 --- a/3-networks-hub-and-spoke/modules/base_shared_vpc/dns.tf +++ b/3-networks-hub-and-spoke/modules/base_shared_vpc/dns.tf @@ -14,28 +14,6 @@ * limitations under the License. */ -locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = local.parent_id -} - -/****************************************** - DNS Hub Project -*****************************************/ - -data "google_projects" "dns_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-dns-hub lifecycleState=ACTIVE" -} - -data "google_compute_network" "vpc_dns_hub" { - name = "vpc-c-dns-hub" - project = data.google_projects.dns_hub.projects[0].project_id -} - /****************************************** Default DNS Policy *****************************************/ @@ -53,6 +31,11 @@ resource "google_dns_policy" "default_policy" { /****************************************** Creates DNS Peering to DNS HUB *****************************************/ +data "google_compute_network" "vpc_dns_hub" { + name = "vpc-c-dns-hub" + project = var.dns_hub_project_id +} + module "peering_zone" { source = "terraform-google-modules/cloud-dns/google" version = "~> 3.1" diff --git a/3-networks-hub-and-spoke/modules/base_shared_vpc/main.tf b/3-networks-hub-and-spoke/modules/base_shared_vpc/main.tf index 0130f5530..7d4276052 100644 --- a/3-networks-hub-and-spoke/modules/base_shared_vpc/main.tf +++ b/3-networks-hub-and-spoke/modules/base_shared_vpc/main.tf @@ -21,21 +21,6 @@ locals { private_googleapis_cidr = module.private_service_connect.private_service_connect_ip } -/****************************************** - Base Network Hub -*****************************************/ - -data "google_projects" "base_net_hub" { - count = var.mode == "spoke" ? 1 : 0 - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-base-net-hub lifecycleState=ACTIVE" -} - -data "google_compute_network" "vpc_base_net_hub" { - count = var.mode == "spoke" ? 1 : 0 - name = "vpc-c-shared-base-hub" - project = data.google_projects.base_net_hub[0].projects[0].project_id -} - /****************************************** Shared VPC configuration *****************************************/ @@ -80,6 +65,11 @@ module "main" { /*************************************************************** VPC Peering Configuration **************************************************************/ +data "google_compute_network" "vpc_base_net_hub" { + count = var.mode == "spoke" ? 1 : 0 + name = "vpc-c-shared-base-hub" + project = var.base_net_hub_project_id +} module "peering" { source = "terraform-google-modules/network/google//modules/network-peering" diff --git a/3-networks-hub-and-spoke/modules/base_shared_vpc/variables.tf b/3-networks-hub-and-spoke/modules/base_shared_vpc/variables.tf index ab7d2c075..c575cd077 100644 --- a/3-networks-hub-and-spoke/modules/base_shared_vpc/variables.tf +++ b/3-networks-hub-and-spoke/modules/base_shared_vpc/variables.tf @@ -24,6 +24,17 @@ variable "project_id" { description = "Project ID for Private Shared VPC." } +variable "dns_hub_project_id" { + type = string + description = "The DNS hub project ID" +} + +variable "base_net_hub_project_id" { + type = string + description = "The base net hub project ID" + default = "" +} + variable "mode" { type = string description = "Network deployment mode, should be set to `hub` or `spoke` when `enable_hub_and_spoke` architecture chosen, keep as `null` otherwise." @@ -127,18 +138,6 @@ variable "nat_num_addresses" { default = 2 } -variable "parent_folder" { - description = "Optional - if using a folder for testing." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created." - type = string - default = "fldr" -} - variable "allow_all_egress_ranges" { description = "List of network ranges to which all egress traffic will be allowed" default = null diff --git a/3-networks-hub-and-spoke/modules/dedicated_interconnect/README.md b/3-networks-hub-and-spoke/modules/dedicated_interconnect/README.md index 746335121..18b1d0bc5 100644 --- a/3-networks-hub-and-spoke/modules/dedicated_interconnect/README.md +++ b/3-networks-hub-and-spoke/modules/dedicated_interconnect/README.md @@ -18,9 +18,7 @@ This module implements the recommendation proposed in [Establishing 99.99% Avail | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| | cloud\_router\_labels | A map of suffixes for labelling vlans with four entries like "vlan\_1" => "suffix1" with keys from `vlan_1` to `vlan_4`. | `map(string)` | `{}` | no | -| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | +| interconnect\_project\_id | Interconnect project ID. | `string` | n/a | yes | | peer\_asn | Peer BGP Autonomous System Number (ASN). | `number` | n/a | yes | | peer\_name | Name of this BGP peer. The name must be 1-63 characters long, and comply with RFC1035. Specifically, the name must be 1-63 characters long and match the regular expression [a-z]([-a-z0-9]\*[a-z0-9])? | `string` | n/a | yes | | region1 | First subnet region. The Dedicated Interconnect module only configures two regions. | `string` | n/a | yes | diff --git a/3-networks-hub-and-spoke/modules/dedicated_interconnect/main.tf b/3-networks-hub-and-spoke/modules/dedicated_interconnect/main.tf index 0380a69ac..f82b466f0 100644 --- a/3-networks-hub-and-spoke/modules/dedicated_interconnect/main.tf +++ b/3-networks-hub-and-spoke/modules/dedicated_interconnect/main.tf @@ -15,21 +15,10 @@ */ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - interconnect_project_id = data.google_projects.interconnect_project.projects[0].project_id - suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") - suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") - suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") - suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") -} - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = local.parent_id -} - -data "google_projects" "interconnect_project" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-interconnect lifecycleState=ACTIVE" + suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") + suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") + suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") + suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") } module "interconnect_attachment1_region1" { @@ -37,7 +26,7 @@ module "interconnect_attachment1_region1" { version = "~> 2.0.0" name = "vl-${var.region1_interconnect1_location}-${var.vpc_name}-${var.region1}-${local.suffix1}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region1 router = var.region1_router1_name @@ -60,7 +49,7 @@ module "interconnect_attachment2_region1" { version = "~> 0.4.0" name = "vl-${var.region1_interconnect2_location}-${var.vpc_name}-${var.region1}-${local.suffix2}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region1 router = var.region1_router2_name @@ -83,7 +72,7 @@ module "interconnect_attachment1_region2" { version = "~> 0.4.0" name = "vl-${var.region2_interconnect1_location}-${var.vpc_name}-${var.region2}-${local.suffix3}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region2 router = var.region2_router1_name @@ -106,7 +95,7 @@ module "interconnect_attachment2_region2" { version = "~> 0.4.0" name = "vl-${var.region2_interconnect2_location}-${var.vpc_name}-${var.region2}-${local.suffix4}" - project = local.interconnect_project_id + project = var.interconnect_project_id region = var.region2 router = var.region2_router2_name diff --git a/3-networks-hub-and-spoke/modules/dedicated_interconnect/variables.tf b/3-networks-hub-and-spoke/modules/dedicated_interconnect/variables.tf index 3a3f71259..2244dcd42 100644 --- a/3-networks-hub-and-spoke/modules/dedicated_interconnect/variables.tf +++ b/3-networks-hub-and-spoke/modules/dedicated_interconnect/variables.tf @@ -14,15 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "interconnect_project_id" { type = string - description = "Organization ID" -} - -variable "parent_folder" { - description = "Optional - if using a folder for testing." - type = string - default = "" + description = "Interconnect project ID." } variable "vpc_name" { @@ -161,9 +155,3 @@ variable "region2_interconnect2_vlan_tag8021q" { description = "The IEEE 802.1Q VLAN tag for this attachment, in the range 2-4094." default = null } - -variable "folder_prefix" { - description = "Name prefix to use for folders created." - type = string - default = "fldr" -} diff --git a/3-networks-hub-and-spoke/modules/partner_interconnect/README.md b/3-networks-hub-and-spoke/modules/partner_interconnect/README.md index a89753d97..8d3b2afb8 100644 --- a/3-networks-hub-and-spoke/modules/partner_interconnect/README.md +++ b/3-networks-hub-and-spoke/modules/partner_interconnect/README.md @@ -19,11 +19,8 @@ Without Hub and Spoke enabled VLAN attachments will be created in `prj-{p|n|d}-s | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| attachment\_project\_id | the Interconnect project ID. | `string` | n/a | yes | | cloud\_router\_labels | A map of suffixes for labelling vlans with four entries like "vlan\_1" => "suffix1" with keys from `vlan_1` to `vlan_4`. | `map(string)` | `{}` | no | -| environment | Environment in which to deploy the Partner Interconnect, must be 'common' if enable\_hub\_and\_spoke=true | `string` | `null` | no | -| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | | preactivate | Preactivate Partner Interconnect attachments, works only for level3 Partner Interconnect | `string` | `false` | no | | region1 | First subnet region. The Partner Interconnect module only configures two regions. | `string` | n/a | yes | | region1\_interconnect1\_location | Name of the interconnect location used in the creation of the Interconnect for the first location of region1 | `string` | n/a | yes | diff --git a/3-networks-hub-and-spoke/modules/partner_interconnect/main.tf b/3-networks-hub-and-spoke/modules/partner_interconnect/main.tf index f5f53e854..9e3274f4e 100644 --- a/3-networks-hub-and-spoke/modules/partner_interconnect/main.tf +++ b/3-networks-hub-and-spoke/modules/partner_interconnect/main.tf @@ -15,30 +15,16 @@ */ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") - suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") - suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") - suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") - - attachment_project_id = data.google_projects.attachment_project.projects[0].project_id - - app_label = "org-${var.vpc_type}-net-hub" - environment_label = "production" + suffix1 = lookup(var.cloud_router_labels, "vlan_1", "cr1") + suffix2 = lookup(var.cloud_router_labels, "vlan_2", "cr2") + suffix3 = lookup(var.cloud_router_labels, "vlan_3", "cr3") + suffix4 = lookup(var.cloud_router_labels, "vlan_4", "cr4") } -data "google_active_folder" "environment" { - display_name = "${var.folder_prefix}-${var.environment}" - parent = local.parent_id -} - -data "google_projects" "attachment_project" { - filter = "parent.id:${split("/", data.google_active_folder.environment.name)[1]} labels.application_name=${local.app_label} labels.environment=${local.environment_label} lifecycleState=ACTIVE" -} resource "google_compute_interconnect_attachment" "interconnect_attachment1_region1" { name = "vl-${var.region1_interconnect1_location}-${var.vpc_name}-${var.region1}-${local.suffix1}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region1 router = var.region1_router1_name @@ -49,7 +35,7 @@ resource "google_compute_interconnect_attachment" "interconnect_attachment1_regi resource "google_compute_interconnect_attachment" "interconnect_attachment2_region1" { name = "vl-${var.region1_interconnect2_location}-${var.vpc_name}-${var.region1}-${local.suffix2}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region1 router = var.region1_router2_name @@ -60,7 +46,7 @@ resource "google_compute_interconnect_attachment" "interconnect_attachment2_regi resource "google_compute_interconnect_attachment" "interconnect_attachment1_region2" { name = "vl-${var.region2_interconnect1_location}-${var.vpc_name}-${var.region2}-${local.suffix1}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region2 router = var.region2_router1_name @@ -71,7 +57,7 @@ resource "google_compute_interconnect_attachment" "interconnect_attachment1_regi resource "google_compute_interconnect_attachment" "interconnect_attachment2_region2" { name = "vl-${var.region2_interconnect2_location}-${var.vpc_name}-${var.region2}-${local.suffix2}" - project = local.attachment_project_id + project = var.attachment_project_id region = var.region2 router = var.region2_router2_name diff --git a/3-networks-hub-and-spoke/modules/partner_interconnect/variables.tf b/3-networks-hub-and-spoke/modules/partner_interconnect/variables.tf index cfadab154..069da8846 100644 --- a/3-networks-hub-and-spoke/modules/partner_interconnect/variables.tf +++ b/3-networks-hub-and-spoke/modules/partner_interconnect/variables.tf @@ -14,15 +14,9 @@ * limitations under the License. */ -variable "org_id" { +variable "attachment_project_id" { type = string - description = "Organization ID" -} - -variable "parent_folder" { - description = "Optional - if using a folder for testing." - type = string - default = "" + description = "the Interconnect project ID." } variable "vpc_name" { @@ -86,24 +80,12 @@ variable "cloud_router_labels" { default = {} } -variable "folder_prefix" { - description = "Name prefix to use for folders created." - type = string - default = "fldr" -} - variable "preactivate" { description = "Preactivate Partner Interconnect attachments, works only for level3 Partner Interconnect" type = string default = false } -variable "environment" { - description = "Environment in which to deploy the Partner Interconnect, must be 'common' if enable_hub_and_spoke=true" - type = string - default = null -} - variable "vpc_type" { description = "To which Shared VPC Host attach the Partner Interconnect - base/restricted" type = string diff --git a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/README.md b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/README.md index 4e7fb1702..f047746b1 100644 --- a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/README.md +++ b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/README.md @@ -11,10 +11,10 @@ | default\_region2 | Second subnet region. The shared vpc modules only configures two regions. | `string` | n/a | yes | | 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 | +| dns\_hub\_project\_id | The DNS hub project ID | `string` | n/a | yes | | domain | The DNS name of peering managed zone, for instance 'example.com.' | `string` | n/a | yes | | 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 | -| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | | members | An allowed list of members (users, service accounts). 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 | @@ -22,10 +22,11 @@ | nat\_num\_addresses\_region1 | Number of external IPs to reserve for region 1 Cloud NAT. | `number` | `2` | no | | nat\_num\_addresses\_region2 | Number of external IPs to reserve for region 2 Cloud NAT. | `number` | `2` | no | | org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | | private\_service\_cidr | CIDR range for private service networking. Used for Cloud SQL and other managed services. | `string` | `null` | no | | project\_id | Project ID for Restricted Shared VPC. | `string` | n/a | yes | | project\_number | Project number for Restricted Shared VPC. It is the project INSIDE the regular service perimeter. | `number` | n/a | yes | +| restricted\_net\_hub\_project\_id | The restricted net hub project ID | `string` | `""` | no | +| restricted\_net\_hub\_project\_number | The restricted net hub project number | `string` | `""` | no | | restricted\_services | List of services to restrict. | `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(map(string))` | `[]` | no | diff --git a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/dns.tf b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/dns.tf index 75180046b..440c178f2 100644 --- a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/dns.tf +++ b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/dns.tf @@ -14,28 +14,6 @@ * limitations under the License. */ -locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = local.parent_id -} - -/****************************************** - DNS Hub Project -*****************************************/ - -data "google_projects" "dns_hub" { - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-dns-hub lifecycleState=ACTIVE" -} - -data "google_compute_network" "vpc_dns_hub" { - name = "vpc-c-dns-hub" - project = data.google_projects.dns_hub.projects[0].project_id -} - /****************************************** Default DNS Policy *****************************************/ @@ -53,6 +31,11 @@ resource "google_dns_policy" "default_policy" { /****************************************** Creates DNS Peering to DNS HUB *****************************************/ +data "google_compute_network" "vpc_dns_hub" { + name = "vpc-c-dns-hub" + project = var.dns_hub_project_id +} + module "peering_zone" { source = "terraform-google-modules/cloud-dns/google" version = "~> 3.1" diff --git a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/main.tf b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/main.tf index 717d62926..71239e083 100644 --- a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/main.tf +++ b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/main.tf @@ -21,21 +21,6 @@ locals { restricted_googleapis_cidr = module.private_service_connect.private_service_connect_ip } -/****************************************** - Restricted Network Hub -*****************************************/ - -data "google_projects" "restricted_net_hub" { - count = var.mode == "spoke" ? 1 : 0 - filter = "parent.id:${split("/", data.google_active_folder.common.name)[1]} labels.application_name=org-restricted-net-hub lifecycleState=ACTIVE" -} - -data "google_compute_network" "vpc_restricted_net_hub" { - count = var.mode == "spoke" ? 1 : 0 - name = "vpc-c-shared-restricted-hub" - project = data.google_projects.restricted_net_hub[0].projects[0].project_id -} - /****************************************** Shared VPC configuration *****************************************/ @@ -81,6 +66,11 @@ module "main" { /*************************************************************** VPC Peering Configuration **************************************************************/ +data "google_compute_network" "vpc_restricted_net_hub" { + count = var.mode == "spoke" ? 1 : 0 + name = "vpc-c-shared-restricted-hub" + project = var.restricted_net_hub_project_id +} module "peering" { source = "terraform-google-modules/network/google//modules/network-peering" diff --git a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/service_control.tf b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/service_control.tf index 5009ff3e6..7abbc958d 100644 --- a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/service_control.tf +++ b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/service_control.tf @@ -21,11 +21,6 @@ locals { bridge_name = "spb_c_to_${local.prefix}_bridge_${random_id.random_access_level_suffix.hex}" } -data "google_project" "restricted_net_hub" { - count = var.mode == "spoke" ? 1 : 0 - project_id = data.google_projects.restricted_net_hub[0].projects[0].project_id -} - resource "random_id" "random_access_level_suffix" { byte_length = 2 } @@ -69,7 +64,7 @@ resource "google_access_context_manager_service_perimeter" "bridge_to_network_hu title = local.bridge_name status { - resources = formatlist("projects/%s", [var.project_number, data.google_project.restricted_net_hub[0].number]) + resources = formatlist("projects/%s", [var.project_number, var.restricted_net_hub_project_number]) } depends_on = [google_access_context_manager_service_perimeter.regular_service_perimeter] diff --git a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/variables.tf b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/variables.tf index 0c01ce81c..792ee8bd7 100644 --- a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/variables.tf +++ b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/variables.tf @@ -34,6 +34,23 @@ variable "project_number" { description = "Project number for Restricted Shared VPC. It is the project INSIDE the regular service perimeter." } +variable "dns_hub_project_id" { + type = string + description = "The DNS hub project ID" +} + +variable "restricted_net_hub_project_id" { + type = string + description = "The restricted net hub project ID" + default = "" +} + +variable "restricted_net_hub_project_number" { + type = string + description = "The restricted net hub project number" + default = "" +} + variable "mode" { type = string description = "Network deployment mode, should be set to `hub` or `spoke` when `enable_hub_and_spoke` architecture chosen, keep as `null` otherwise." @@ -141,18 +158,6 @@ variable "restricted_services" { description = "List of services to restrict." } -variable "parent_folder" { - description = "Optional - if using a folder for testing." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created." - type = string - default = "fldr" -} - variable "allow_all_egress_ranges" { description = "List of network ranges to which all egress traffic will be allowed" default = null diff --git a/3-networks-hub-and-spoke/modules/vpn-ha/README.md b/3-networks-hub-and-spoke/modules/vpn-ha/README.md index 0480eef1a..5d8374695 100755 --- a/3-networks-hub-and-spoke/modules/vpn-ha/README.md +++ b/3-networks-hub-and-spoke/modules/vpn-ha/README.md @@ -23,12 +23,9 @@ If you are not able to use Dedicated Interconnect or Partner Interconnect you ca | bgp\_peer\_asn | BGP ASN for cloud routes. | `number` | n/a | yes | | default\_region1 | Default region 1 for Cloud Routers | `string` | n/a | yes | | default\_region2 | Default region 2 for Cloud Routers | `string` | n/a | yes | -| environment | Environment for the VPN configuration. Valid options are development, non-production, production | `string` | n/a | yes | -| folder\_prefix | Name prefix to use for folders created. | `string` | `"fldr"` | no | +| env\_secret\_project\_id | the environment secrets project ID | `string` | n/a | yes | | on\_prem\_router\_ip\_address1 | On-Prem Router IP address | `string` | n/a | yes | | on\_prem\_router\_ip\_address2 | On-Prem Router IP address | `string` | n/a | yes | -| org\_id | Organization ID | `string` | n/a | yes | -| parent\_folder | Optional - if using a folder for testing. | `string` | `""` | no | | project\_id | VPC Project ID | `string` | n/a | yes | | region1\_router1\_name | Name of the Router 1 for Region 1 where the attachment resides. | `string` | n/a | yes | | region1\_router1\_tunnel0\_bgp\_peer\_address | BGP session address for router 1 in region 1 tunnel 0 | `string` | n/a | yes | diff --git a/3-networks-hub-and-spoke/modules/vpn-ha/main.tf b/3-networks-hub-and-spoke/modules/vpn-ha/main.tf index e10cf1c49..93fdf68ee 100755 --- a/3-networks-hub-and-spoke/modules/vpn-ha/main.tf +++ b/3-networks-hub-and-spoke/modules/vpn-ha/main.tf @@ -19,23 +19,12 @@ *****************************************/ locals { - parent_id = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" - network_name = "vpc-${var.vpc_name}" - env_secret_project_id = data.google_projects.env_secrets.projects[0].project_id - psk_secret_data = chomp(data.google_secret_manager_secret_version.psk.secret_data) -} - -data "google_active_folder" "env" { - display_name = "${var.folder_prefix}-${var.environment}" - parent = local.parent_id -} - -data "google_projects" "env_secrets" { - filter = "parent.id:${split("/", data.google_active_folder.env.name)[1]} labels.application_name=env-secrets labels.environment=${var.environment} lifecycleState=ACTIVE" + network_name = "vpc-${var.vpc_name}" + psk_secret_data = chomp(data.google_secret_manager_secret_version.psk.secret_data) } data "google_secret_manager_secret_version" "psk" { - project = local.env_secret_project_id + project = var.env_secret_project_id secret = var.vpn_psk_secret_name } diff --git a/3-networks-hub-and-spoke/modules/vpn-ha/variables.tf b/3-networks-hub-and-spoke/modules/vpn-ha/variables.tf index 6b426f129..e85f6f85d 100644 --- a/3-networks-hub-and-spoke/modules/vpn-ha/variables.tf +++ b/3-networks-hub-and-spoke/modules/vpn-ha/variables.tf @@ -19,6 +19,11 @@ variable "project_id" { description = "VPC Project ID" } +variable "env_secret_project_id" { + type = string + description = "the environment secrets project ID" +} + variable "default_region1" { type = string description = "Default region 1 for Cloud Routers" @@ -29,16 +34,6 @@ variable "default_region2" { description = "Default region 2 for Cloud Routers" } -variable "environment" { - type = string - description = "Environment for the VPN configuration. Valid options are development, non-production, production" -} - -variable "org_id" { - type = string - description = "Organization ID" -} - variable "vpn_psk_secret_name" { type = string description = "The name of the secret to retrieve from secret manager. This will be retrieved from the environment secrets project." @@ -163,15 +158,3 @@ variable "region2_router2_tunnel1_bgp_peer_range" { type = string description = "BGP session range for router 2 in region 1 tunnel 1" } - -variable "parent_folder" { - description = "Optional - if using a folder for testing." - type = string - default = "" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created." - type = string - default = "fldr" -} diff --git a/4-projects/README.md b/4-projects/README.md index c93e3635c..1864ea7f9 100644 --- a/4-projects/README.md +++ b/4-projects/README.md @@ -68,53 +68,17 @@ This pipeline can be utilized for deploying resources in projects across develop 1. 1-org executed successfully. 1. 2-environments executed successfully. 1. 3-networks executed successfully. -1. Obtain the value for the `access_context_manager_policy_id` variable. - - ```bash - gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)" - ``` 1. For the manual step described in this document, you need [Terraform](https://www.terraform.io/downloads.html) version 1.0.0 or later to be installed. **Note:** Make sure that you use version 1.0.0 or later of Terraform throughout this series. Otherwise, you might experience Terraform state snapshot lock errors. -1. Obtain the values for the `perimeter_name` for each environment variable. - - ```bash - gcloud access-context-manager perimeters list --policy ACCESS_CONTEXT_MANAGER_POLICY_ID --format="value(name)" - ``` - - **Note:** If you have more than one service perimeter for each environment, you can also get the values from the `restricted_service_perimeter_name` output from each of the`3-networks` environments. - - If you are using Cloud Build you can also search for the values in the outputs from the build logs: - - ```console - gcloud builds list \ - --project=YOUR_CLOUD_BUILD_PROJECT_ID \ - --filter="status=SUCCESS \ - AND source.repoSource.repoName=gcp-networks \ - AND substitutions.BRANCH_NAME=development" \ - --format="value(id)" - ``` - - Use the result of this command as the `BUILD_ID` value in the next command: - - ```console - gcloud builds log BUILD_ID \ - --project=YOUR_CLOUD_BUILD_PROJECT_ID | \ - grep "restricted_service_perimeter_name = " - ``` - - Change the `BRANCH_NAME` from `development` to `non-production` or `production` for the other two service perimeters. - ### Troubleshooting Please refer to [troubleshooting](../docs/TROUBLESHOOTING.md) if you run into issues during this step. ## Usage -**Note:** You need to set variable `enable_hub_and_spoke` to `true` to be able to use the **Hub-and-Spoke** architecture detailed in the **Networking** section of the [google cloud security foundations guide](https://services.google.com/fh/files/misc/google-cloud-security-foundations-guide.pdf). - **Note:** If you are using MacOS, replace `cp -RT` with `cp -R` in the relevant commands. The `-T` flag is needed for Linux, but causes problems for MacOS. @@ -147,10 +111,9 @@ commands. The `-T` flag is needed for Linux, but causes problems for MacOS. ``` 1. Rename `common.auto.example.tfvars` to `common.auto.tfvars` and update the file with values from your environment and bootstrap. See any of the business unit envs folders [README.md](./business_unit_1/development/README.md) files for additional information on the values in the `common.auto.tfvars` file. 1. Rename `shared.auto.example.tfvars` to `shared.auto.tfvars` and update the file with values from your environment and bootstrap. See any of the business unit shared envs folders [README.md](./business_unit_1/shared/README.md) files for additional information on the values in the `shared.auto.example.tfvars`. -1. Rename `development.auto.example.tfvars` to `development.auto.tfvars` and update the file with the `perimeter_name` that starts with `sp_d_shared_restricted`. -1. Rename `non-production.auto.example.tfvars` to `non-production.auto.tfvars` and update the file with the `perimeter_name` that starts with `sp_n_shared_restricted`. -1. Rename `production.auto.example.tfvars` to `production.auto.tfvars` and update the file with the `perimeter_name` that starts with `sp_p_shared_restricted`. -1. Rename `access_context.auto.example.tfvars` to `access_context.auto.tfvars` and update the file with the `access_context_manager_policy_id`. +1. Rename `development.auto.example.tfvars` to `development.auto.tfvars`. +1. Rename `non-production.auto.example.tfvars` to `non-production.auto.tfvars`. +1. Rename `production.auto.example.tfvars` to `production.auto.tfvars`. 1. You need to manually plan and apply only once the `business_unit_1/shared` environment since `development`, `non-production`, and `production` depend on it. 1. Run `cd ./business_unit_1/shared/`. 1. Update `backend.tf` with your bucket name from the 0-bootstrap step. @@ -158,11 +121,8 @@ commands. The `-T` flag is needed for Linux, but causes problems for MacOS. 1. Run `terraform init`. 1. Run `terraform plan` and review output. 1. Run `terraform apply`. - 1. Run `terraform output cloudbuild_sa` to get the cloud build service account from the apply step. 1. If you would like the bucket to be replaced by cloud build at run time, change the bucket name back to `UPDATE_ME` 1. Once you have done the instructions for the `business_unit_1`, you need to repeat same steps for `business_unit_2` folder. -1. Rename `business_unit_1.auto.example.tfvars` to `business_unit_1.auto.tfvars` and update the file with the `app_infra_pipeline_cloudbuild_sa` which is the output of `cloudbuild_sa` from `business_unit_1/shared` steps. -1. Rename `business_unit_2.auto.example.tfvars` to `business_unit_2.auto.tfvars` and update the file with the `app_infra_pipeline_cloudbuild_sa` which is the output of `cloudbuild_sa` from `business_unit_2/shared` steps. 1. Commit changes. ``` git add . diff --git a/4-projects/access_context.auto.example.tfvars b/4-projects/access_context.auto.example.tfvars deleted file mode 100644 index dd6c65108..000000000 --- a/4-projects/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 = 000000000000 diff --git a/4-projects/business_unit_1.auto.example.tfvars b/4-projects/business_unit_1.auto.example.tfvars deleted file mode 100644 index 2f150efee..000000000 --- a/4-projects/business_unit_1.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. - */ - -app_infra_pipeline_cloudbuild_sa = "@cloudbuild.gserviceaccount.com" diff --git a/4-projects/business_unit_1/development/README.md b/4-projects/business_unit_1/development/README.md index 0d81097ab..e20008b92 100644 --- a/4-projects/business_unit_1/development/README.md +++ b/4-projects/business_unit_1/development/README.md @@ -3,16 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | n/a | yes | -| app\_infra\_pipeline\_cloudbuild\_sa | Cloud Build SA used for deploying infrastructure | `string` | n/a | yes | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | -| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `"US"` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `"us"` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | -| perimeter\_name | Access context manager service perimeter name to attach the restricted svpc project. | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs diff --git a/4-projects/business_unit_1/development/access_context.auto.tfvars b/4-projects/business_unit_1/development/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/4-projects/business_unit_1/development/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_1/development/business_unit_1.auto.tfvars b/4-projects/business_unit_1/development/business_unit_1.auto.tfvars deleted file mode 120000 index bb874fea3..000000000 --- a/4-projects/business_unit_1/development/business_unit_1.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../business_unit_1.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_1/development/main.tf b/4-projects/business_unit_1/development/main.tf index 1da1cfde3..eb1a4f31c 100644 --- a/4-projects/business_unit_1/development/main.tf +++ b/4-projects/business_unit_1/development/main.tf @@ -14,21 +14,14 @@ * limitations under the License. */ - module "env" { source = "../../modules/base_env" - env = "development" - business_code = "bu1" - business_unit = "business_unit_1" - org_id = var.org_id - billing_account = var.billing_account - access_context_manager_policy_id = var.access_context_manager_policy_id - parent_folder = var.parent_folder - perimeter_name = var.perimeter_name - peering_module_depends_on = var.peering_module_depends_on - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke - app_infra_pipeline_cloudbuild_sa = var.app_infra_pipeline_cloudbuild_sa + env = "development" + business_code = "bu1" + business_unit = "business_unit_1" + backend_bucket = var.backend_bucket + location_kms = var.location_kms + location_gcs = var.location_gcs + peering_module_depends_on = var.peering_module_depends_on } diff --git a/4-projects/business_unit_1/development/outputs.tf b/4-projects/business_unit_1/development/outputs.tf index 77681648a..4098ad611 100644 --- a/4-projects/business_unit_1/development/outputs.tf +++ b/4-projects/business_unit_1/development/outputs.tf @@ -51,7 +51,7 @@ output "restricted_shared_vpc_project_number" { output "vpc_service_control_perimeter_name" { description = "VPC Service Control name." - value = var.perimeter_name + value = module.env.vpc_service_control_perimeter_name } output "restricted_enabled_apis" { @@ -61,7 +61,7 @@ output "restricted_enabled_apis" { output "access_context_manager_policy_id" { description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id + value = module.env.access_context_manager_policy_id } output "peering_complete" { diff --git a/4-projects/business_unit_1/development/variables.tf b/4-projects/business_unit_1/development/variables.tf index 7b3389d79..a28287965 100644 --- a/4-projects/business_unit_1/development/variables.tf +++ b/4-projects/business_unit_1/development/variables.tf @@ -14,30 +14,21 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string } -variable "billing_account" { - description = "The ID of the billing account to associated this project with" +variable "location_kms" { + description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string + default = "us" } -variable "access_context_manager_policy_id" { - type = string - description = "The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "perimeter_name" { - description = "Access context manager service perimeter name to attach the restricted svpc project." +variable "location_gcs" { + description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string + default = "US" } variable "peering_module_depends_on" { @@ -45,26 +36,3 @@ variable "peering_module_depends_on" { type = list(any) default = [] } - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "enable_hub_and_spoke" { - description = "Enable Hub-and-Spoke architecture." - type = bool - default = false -} - -variable "app_infra_pipeline_cloudbuild_sa" { - description = "Cloud Build SA used for deploying infrastructure" - type = string -} diff --git a/4-projects/business_unit_1/non-production/README.md b/4-projects/business_unit_1/non-production/README.md index 0d81097ab..e20008b92 100644 --- a/4-projects/business_unit_1/non-production/README.md +++ b/4-projects/business_unit_1/non-production/README.md @@ -3,16 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | n/a | yes | -| app\_infra\_pipeline\_cloudbuild\_sa | Cloud Build SA used for deploying infrastructure | `string` | n/a | yes | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | -| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `"US"` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `"us"` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | -| perimeter\_name | Access context manager service perimeter name to attach the restricted svpc project. | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs diff --git a/4-projects/business_unit_1/non-production/access_context.auto.tfvars b/4-projects/business_unit_1/non-production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/4-projects/business_unit_1/non-production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_1/non-production/business_unit_1.auto.tfvars b/4-projects/business_unit_1/non-production/business_unit_1.auto.tfvars deleted file mode 120000 index bb874fea3..000000000 --- a/4-projects/business_unit_1/non-production/business_unit_1.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../business_unit_1.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_1/non-production/main.tf b/4-projects/business_unit_1/non-production/main.tf index 097ec2744..f74029c83 100644 --- a/4-projects/business_unit_1/non-production/main.tf +++ b/4-projects/business_unit_1/non-production/main.tf @@ -14,21 +14,14 @@ * limitations under the License. */ - module "env" { source = "../../modules/base_env" - env = "non-production" - business_code = "bu1" - business_unit = "business_unit_1" - org_id = var.org_id - billing_account = var.billing_account - access_context_manager_policy_id = var.access_context_manager_policy_id - parent_folder = var.parent_folder - perimeter_name = var.perimeter_name - peering_module_depends_on = var.peering_module_depends_on - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke - app_infra_pipeline_cloudbuild_sa = var.app_infra_pipeline_cloudbuild_sa + env = "non-production" + business_code = "bu1" + business_unit = "business_unit_1" + backend_bucket = var.backend_bucket + location_kms = var.location_kms + location_gcs = var.location_gcs + peering_module_depends_on = var.peering_module_depends_on } diff --git a/4-projects/business_unit_1/non-production/outputs.tf b/4-projects/business_unit_1/non-production/outputs.tf index 77681648a..4098ad611 100644 --- a/4-projects/business_unit_1/non-production/outputs.tf +++ b/4-projects/business_unit_1/non-production/outputs.tf @@ -51,7 +51,7 @@ output "restricted_shared_vpc_project_number" { output "vpc_service_control_perimeter_name" { description = "VPC Service Control name." - value = var.perimeter_name + value = module.env.vpc_service_control_perimeter_name } output "restricted_enabled_apis" { @@ -61,7 +61,7 @@ output "restricted_enabled_apis" { output "access_context_manager_policy_id" { description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id + value = module.env.access_context_manager_policy_id } output "peering_complete" { diff --git a/4-projects/business_unit_1/non-production/variables.tf b/4-projects/business_unit_1/non-production/variables.tf index 7b3389d79..a28287965 100644 --- a/4-projects/business_unit_1/non-production/variables.tf +++ b/4-projects/business_unit_1/non-production/variables.tf @@ -14,30 +14,21 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string } -variable "billing_account" { - description = "The ID of the billing account to associated this project with" +variable "location_kms" { + description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string + default = "us" } -variable "access_context_manager_policy_id" { - type = string - description = "The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "perimeter_name" { - description = "Access context manager service perimeter name to attach the restricted svpc project." +variable "location_gcs" { + description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string + default = "US" } variable "peering_module_depends_on" { @@ -45,26 +36,3 @@ variable "peering_module_depends_on" { type = list(any) default = [] } - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "enable_hub_and_spoke" { - description = "Enable Hub-and-Spoke architecture." - type = bool - default = false -} - -variable "app_infra_pipeline_cloudbuild_sa" { - description = "Cloud Build SA used for deploying infrastructure" - type = string -} diff --git a/4-projects/business_unit_1/production/README.md b/4-projects/business_unit_1/production/README.md index 0d81097ab..e20008b92 100644 --- a/4-projects/business_unit_1/production/README.md +++ b/4-projects/business_unit_1/production/README.md @@ -3,16 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | n/a | yes | -| app\_infra\_pipeline\_cloudbuild\_sa | Cloud Build SA used for deploying infrastructure | `string` | n/a | yes | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | -| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `"US"` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `"us"` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | -| perimeter\_name | Access context manager service perimeter name to attach the restricted svpc project. | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs diff --git a/4-projects/business_unit_1/production/access_context.auto.tfvars b/4-projects/business_unit_1/production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/4-projects/business_unit_1/production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_1/production/business_unit_1.auto.tfvars b/4-projects/business_unit_1/production/business_unit_1.auto.tfvars deleted file mode 120000 index bb874fea3..000000000 --- a/4-projects/business_unit_1/production/business_unit_1.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../business_unit_1.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_1/production/main.tf b/4-projects/business_unit_1/production/main.tf index 965db24fc..89cc7881b 100644 --- a/4-projects/business_unit_1/production/main.tf +++ b/4-projects/business_unit_1/production/main.tf @@ -14,21 +14,14 @@ * limitations under the License. */ - module "env" { source = "../../modules/base_env" - env = "production" - business_code = "bu1" - business_unit = "business_unit_1" - org_id = var.org_id - billing_account = var.billing_account - access_context_manager_policy_id = var.access_context_manager_policy_id - parent_folder = var.parent_folder - perimeter_name = var.perimeter_name - peering_module_depends_on = var.peering_module_depends_on - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke - app_infra_pipeline_cloudbuild_sa = var.app_infra_pipeline_cloudbuild_sa + env = "production" + business_code = "bu1" + business_unit = "business_unit_1" + backend_bucket = var.backend_bucket + location_kms = var.location_kms + location_gcs = var.location_gcs + peering_module_depends_on = var.peering_module_depends_on } diff --git a/4-projects/business_unit_1/production/outputs.tf b/4-projects/business_unit_1/production/outputs.tf index 77681648a..4098ad611 100644 --- a/4-projects/business_unit_1/production/outputs.tf +++ b/4-projects/business_unit_1/production/outputs.tf @@ -51,7 +51,7 @@ output "restricted_shared_vpc_project_number" { output "vpc_service_control_perimeter_name" { description = "VPC Service Control name." - value = var.perimeter_name + value = module.env.vpc_service_control_perimeter_name } output "restricted_enabled_apis" { @@ -61,7 +61,7 @@ output "restricted_enabled_apis" { output "access_context_manager_policy_id" { description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id + value = module.env.access_context_manager_policy_id } output "peering_complete" { diff --git a/4-projects/business_unit_1/production/variables.tf b/4-projects/business_unit_1/production/variables.tf index 7b3389d79..a28287965 100644 --- a/4-projects/business_unit_1/production/variables.tf +++ b/4-projects/business_unit_1/production/variables.tf @@ -14,30 +14,21 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string } -variable "billing_account" { - description = "The ID of the billing account to associated this project with" +variable "location_kms" { + description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string + default = "us" } -variable "access_context_manager_policy_id" { - type = string - description = "The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "perimeter_name" { - description = "Access context manager service perimeter name to attach the restricted svpc project." +variable "location_gcs" { + description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string + default = "US" } variable "peering_module_depends_on" { @@ -45,26 +36,3 @@ variable "peering_module_depends_on" { type = list(any) default = [] } - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "enable_hub_and_spoke" { - description = "Enable Hub-and-Spoke architecture." - type = bool - default = false -} - -variable "app_infra_pipeline_cloudbuild_sa" { - description = "Cloud Build SA used for deploying infrastructure" - type = string -} diff --git a/4-projects/business_unit_1/shared/README.md b/4-projects/business_unit_1/shared/README.md index d35216266..1a3366eb9 100644 --- a/4-projects/business_unit_1/shared/README.md +++ b/4-projects/business_unit_1/shared/README.md @@ -5,14 +5,10 @@ |------|-------------|------|---------|:--------:| | 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}` | `string` | `null` | no | | alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | budget\_amount | The amount to use as the budget | `number` | `1000` | no | | default\_region | Default region to create resources where applicable. | `string` | `"us-central1"` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | | impersonate\_service\_account | Service account email of the account to impersonate to run gcloud build submit | `string` | n/a | yes | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs 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 c669bbccc..dbcff1c9a 100644 --- a/4-projects/business_unit_1/shared/example_infra_pipeline.tf +++ b/4-projects/business_unit_1/shared/example_infra_pipeline.tf @@ -16,14 +16,14 @@ module "app_infra_cloudbuild_project" { source = "../../modules/single_project" - org_id = var.org_id - billing_account = var.billing_account - folder_id = data.google_active_folder.common.name + org_id = local.org_id + billing_account = local.billing_account + folder_id = local.common_folder_name environment = "common" alert_spent_percents = var.alert_spent_percents alert_pubsub_topic = var.alert_pubsub_topic budget_amount = var.budget_amount - project_prefix = var.project_prefix + project_prefix = local.project_prefix activate_apis = [ "cloudbuild.googleapis.com", "sourcerepo.googleapis.com", @@ -45,8 +45,8 @@ module "infra_pipelines" { source = "../../modules/infra_pipelines" impersonate_service_account = var.impersonate_service_account cloudbuild_project_id = module.app_infra_cloudbuild_project.project_id - project_prefix = var.project_prefix - billing_account = var.billing_account + project_prefix = local.project_prefix + billing_account = local.billing_account default_region = var.default_region bucket_region = var.default_region app_infra_repos = ["bu1-example-app"] diff --git a/4-projects/business_unit_1/shared/folder.tf b/4-projects/business_unit_1/shared/folder.tf deleted file mode 100644 index 7e7311605..000000000 --- a/4-projects/business_unit_1/shared/folder.tf +++ /dev/null @@ -1,20 +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. - */ - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} diff --git a/4-projects/business_unit_1/shared/main.tf b/4-projects/business_unit_1/shared/main.tf new file mode 100644 index 000000000..26ebb3071 --- /dev/null +++ b/4-projects/business_unit_1/shared/main.tf @@ -0,0 +1,44 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder + parent = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + common_folder_name = data.terraform_remote_state.org.outputs.common_folder_name + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } +} + +data "terraform_remote_state" "org" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/org/state" + } +} diff --git a/4-projects/business_unit_1/shared/variables.tf b/4-projects/business_unit_1/shared/variables.tf index 9f2bdae72..8e7f6c569 100644 --- a/4-projects/business_unit_1/shared/variables.tf +++ b/4-projects/business_unit_1/shared/variables.tf @@ -25,22 +25,6 @@ variable "impersonate_service_account" { type = string } -variable "org_id" { - description = "The organization id for the associated services" - type = string -} - -variable "billing_account" { - description = "The ID of the billing account to associated this project with" - type = string -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - variable "alert_spent_percents" { description = "A list of percentages of the budget to alert on when threshold is exceeded" type = list(number) @@ -59,14 +43,7 @@ variable "budget_amount" { default = 1000 } -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - default = "prj" } diff --git a/4-projects/business_unit_2.auto.example.tfvars b/4-projects/business_unit_2.auto.example.tfvars deleted file mode 100644 index 03f2a179b..000000000 --- a/4-projects/business_unit_2.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. - */ - -app_infra_pipeline_cloudbuild_sa = "@cloudbuild.gserviceaccount.com" diff --git a/4-projects/business_unit_2/development/README.md b/4-projects/business_unit_2/development/README.md index 0d81097ab..e20008b92 100644 --- a/4-projects/business_unit_2/development/README.md +++ b/4-projects/business_unit_2/development/README.md @@ -3,16 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | n/a | yes | -| app\_infra\_pipeline\_cloudbuild\_sa | Cloud Build SA used for deploying infrastructure | `string` | n/a | yes | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | -| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `"US"` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `"us"` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | -| perimeter\_name | Access context manager service perimeter name to attach the restricted svpc project. | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs diff --git a/4-projects/business_unit_2/development/access_context.auto.tfvars b/4-projects/business_unit_2/development/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/4-projects/business_unit_2/development/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_2/development/business_unit_2.auto.tfvars b/4-projects/business_unit_2/development/business_unit_2.auto.tfvars deleted file mode 120000 index 36de0895f..000000000 --- a/4-projects/business_unit_2/development/business_unit_2.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../business_unit_2.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_2/development/main.tf b/4-projects/business_unit_2/development/main.tf index 88c031e4c..ead64a3d4 100644 --- a/4-projects/business_unit_2/development/main.tf +++ b/4-projects/business_unit_2/development/main.tf @@ -14,21 +14,14 @@ * limitations under the License. */ - module "env" { source = "../../modules/base_env" - env = "development" - business_code = "bu2" - business_unit = "business_unit_2" - org_id = var.org_id - billing_account = var.billing_account - access_context_manager_policy_id = var.access_context_manager_policy_id - parent_folder = var.parent_folder - perimeter_name = var.perimeter_name - peering_module_depends_on = var.peering_module_depends_on - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke - app_infra_pipeline_cloudbuild_sa = var.app_infra_pipeline_cloudbuild_sa + env = "development" + business_code = "bu2" + business_unit = "business_unit_2" + backend_bucket = var.backend_bucket + location_kms = var.location_kms + location_gcs = var.location_gcs + peering_module_depends_on = var.peering_module_depends_on } diff --git a/4-projects/business_unit_2/development/outputs.tf b/4-projects/business_unit_2/development/outputs.tf index 77681648a..4098ad611 100644 --- a/4-projects/business_unit_2/development/outputs.tf +++ b/4-projects/business_unit_2/development/outputs.tf @@ -51,7 +51,7 @@ output "restricted_shared_vpc_project_number" { output "vpc_service_control_perimeter_name" { description = "VPC Service Control name." - value = var.perimeter_name + value = module.env.vpc_service_control_perimeter_name } output "restricted_enabled_apis" { @@ -61,7 +61,7 @@ output "restricted_enabled_apis" { output "access_context_manager_policy_id" { description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id + value = module.env.access_context_manager_policy_id } output "peering_complete" { diff --git a/4-projects/business_unit_2/development/variables.tf b/4-projects/business_unit_2/development/variables.tf index 7b3389d79..a28287965 100644 --- a/4-projects/business_unit_2/development/variables.tf +++ b/4-projects/business_unit_2/development/variables.tf @@ -14,30 +14,21 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string } -variable "billing_account" { - description = "The ID of the billing account to associated this project with" +variable "location_kms" { + description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string + default = "us" } -variable "access_context_manager_policy_id" { - type = string - description = "The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "perimeter_name" { - description = "Access context manager service perimeter name to attach the restricted svpc project." +variable "location_gcs" { + description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string + default = "US" } variable "peering_module_depends_on" { @@ -45,26 +36,3 @@ variable "peering_module_depends_on" { type = list(any) default = [] } - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "enable_hub_and_spoke" { - description = "Enable Hub-and-Spoke architecture." - type = bool - default = false -} - -variable "app_infra_pipeline_cloudbuild_sa" { - description = "Cloud Build SA used for deploying infrastructure" - type = string -} diff --git a/4-projects/business_unit_2/non-production/README.md b/4-projects/business_unit_2/non-production/README.md index 0d81097ab..e20008b92 100644 --- a/4-projects/business_unit_2/non-production/README.md +++ b/4-projects/business_unit_2/non-production/README.md @@ -3,16 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | n/a | yes | -| app\_infra\_pipeline\_cloudbuild\_sa | Cloud Build SA used for deploying infrastructure | `string` | n/a | yes | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | -| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `"US"` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `"us"` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | -| perimeter\_name | Access context manager service perimeter name to attach the restricted svpc project. | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs diff --git a/4-projects/business_unit_2/non-production/access_context.auto.tfvars b/4-projects/business_unit_2/non-production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/4-projects/business_unit_2/non-production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_2/non-production/business_unit_2.auto.tfvars b/4-projects/business_unit_2/non-production/business_unit_2.auto.tfvars deleted file mode 120000 index 36de0895f..000000000 --- a/4-projects/business_unit_2/non-production/business_unit_2.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../business_unit_2.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_2/non-production/main.tf b/4-projects/business_unit_2/non-production/main.tf index a1dc7908e..ad3eb88d8 100644 --- a/4-projects/business_unit_2/non-production/main.tf +++ b/4-projects/business_unit_2/non-production/main.tf @@ -14,21 +14,14 @@ * limitations under the License. */ - module "env" { source = "../../modules/base_env" - env = "non-production" - business_code = "bu2" - business_unit = "business_unit_2" - org_id = var.org_id - billing_account = var.billing_account - access_context_manager_policy_id = var.access_context_manager_policy_id - parent_folder = var.parent_folder - perimeter_name = var.perimeter_name - peering_module_depends_on = var.peering_module_depends_on - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke - app_infra_pipeline_cloudbuild_sa = var.app_infra_pipeline_cloudbuild_sa + env = "non-production" + business_code = "bu2" + business_unit = "business_unit_2" + backend_bucket = var.backend_bucket + location_kms = var.location_kms + location_gcs = var.location_gcs + peering_module_depends_on = var.peering_module_depends_on } diff --git a/4-projects/business_unit_2/non-production/outputs.tf b/4-projects/business_unit_2/non-production/outputs.tf index 77681648a..4098ad611 100644 --- a/4-projects/business_unit_2/non-production/outputs.tf +++ b/4-projects/business_unit_2/non-production/outputs.tf @@ -51,7 +51,7 @@ output "restricted_shared_vpc_project_number" { output "vpc_service_control_perimeter_name" { description = "VPC Service Control name." - value = var.perimeter_name + value = module.env.vpc_service_control_perimeter_name } output "restricted_enabled_apis" { @@ -61,7 +61,7 @@ output "restricted_enabled_apis" { output "access_context_manager_policy_id" { description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id + value = module.env.access_context_manager_policy_id } output "peering_complete" { diff --git a/4-projects/business_unit_2/non-production/variables.tf b/4-projects/business_unit_2/non-production/variables.tf index 7b3389d79..a28287965 100644 --- a/4-projects/business_unit_2/non-production/variables.tf +++ b/4-projects/business_unit_2/non-production/variables.tf @@ -14,30 +14,21 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string } -variable "billing_account" { - description = "The ID of the billing account to associated this project with" +variable "location_kms" { + description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string + default = "us" } -variable "access_context_manager_policy_id" { - type = string - description = "The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "perimeter_name" { - description = "Access context manager service perimeter name to attach the restricted svpc project." +variable "location_gcs" { + description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string + default = "US" } variable "peering_module_depends_on" { @@ -45,26 +36,3 @@ variable "peering_module_depends_on" { type = list(any) default = [] } - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "enable_hub_and_spoke" { - description = "Enable Hub-and-Spoke architecture." - type = bool - default = false -} - -variable "app_infra_pipeline_cloudbuild_sa" { - description = "Cloud Build SA used for deploying infrastructure" - type = string -} diff --git a/4-projects/business_unit_2/production/README.md b/4-projects/business_unit_2/production/README.md index 0d81097ab..e20008b92 100644 --- a/4-projects/business_unit_2/production/README.md +++ b/4-projects/business_unit_2/production/README.md @@ -3,16 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | n/a | yes | -| app\_infra\_pipeline\_cloudbuild\_sa | Cloud Build SA used for deploying infrastructure | `string` | n/a | yes | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | -| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `"US"` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `"us"` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | -| perimeter\_name | Access context manager service perimeter name to attach the restricted svpc project. | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs diff --git a/4-projects/business_unit_2/production/access_context.auto.tfvars b/4-projects/business_unit_2/production/access_context.auto.tfvars deleted file mode 120000 index b0cccce77..000000000 --- a/4-projects/business_unit_2/production/access_context.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../access_context.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_2/production/business_unit_2.auto.tfvars b/4-projects/business_unit_2/production/business_unit_2.auto.tfvars deleted file mode 120000 index 36de0895f..000000000 --- a/4-projects/business_unit_2/production/business_unit_2.auto.tfvars +++ /dev/null @@ -1 +0,0 @@ -../../business_unit_2.auto.tfvars \ No newline at end of file diff --git a/4-projects/business_unit_2/production/main.tf b/4-projects/business_unit_2/production/main.tf index 4dbdc00f9..477297f73 100644 --- a/4-projects/business_unit_2/production/main.tf +++ b/4-projects/business_unit_2/production/main.tf @@ -14,21 +14,14 @@ * limitations under the License. */ - module "env" { source = "../../modules/base_env" - env = "production" - business_code = "bu2" - business_unit = "business_unit_2" - org_id = var.org_id - billing_account = var.billing_account - access_context_manager_policy_id = var.access_context_manager_policy_id - parent_folder = var.parent_folder - perimeter_name = var.perimeter_name - peering_module_depends_on = var.peering_module_depends_on - project_prefix = var.project_prefix - folder_prefix = var.folder_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke - app_infra_pipeline_cloudbuild_sa = var.app_infra_pipeline_cloudbuild_sa + env = "production" + business_code = "bu2" + business_unit = "business_unit_2" + backend_bucket = var.backend_bucket + location_kms = var.location_kms + location_gcs = var.location_gcs + peering_module_depends_on = var.peering_module_depends_on } diff --git a/4-projects/business_unit_2/production/outputs.tf b/4-projects/business_unit_2/production/outputs.tf index 77681648a..4098ad611 100644 --- a/4-projects/business_unit_2/production/outputs.tf +++ b/4-projects/business_unit_2/production/outputs.tf @@ -51,7 +51,7 @@ output "restricted_shared_vpc_project_number" { output "vpc_service_control_perimeter_name" { description = "VPC Service Control name." - value = var.perimeter_name + value = module.env.vpc_service_control_perimeter_name } output "restricted_enabled_apis" { @@ -61,7 +61,7 @@ output "restricted_enabled_apis" { output "access_context_manager_policy_id" { description = "Access Context Manager Policy ID." - value = var.access_context_manager_policy_id + value = module.env.access_context_manager_policy_id } output "peering_complete" { diff --git a/4-projects/business_unit_2/production/variables.tf b/4-projects/business_unit_2/production/variables.tf index 7b3389d79..a28287965 100644 --- a/4-projects/business_unit_2/production/variables.tf +++ b/4-projects/business_unit_2/production/variables.tf @@ -14,30 +14,21 @@ * limitations under the License. */ -variable "org_id" { - description = "The organization id for the associated services" +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string } -variable "billing_account" { - description = "The ID of the billing account to associated this project with" +variable "location_kms" { + description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string + default = "us" } -variable "access_context_manager_policy_id" { - type = string - description = "The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "perimeter_name" { - description = "Access context manager service perimeter name to attach the restricted svpc project." +variable "location_gcs" { + description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string + default = "US" } variable "peering_module_depends_on" { @@ -45,26 +36,3 @@ variable "peering_module_depends_on" { type = list(any) default = [] } - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "enable_hub_and_spoke" { - description = "Enable Hub-and-Spoke architecture." - type = bool - default = false -} - -variable "app_infra_pipeline_cloudbuild_sa" { - description = "Cloud Build SA used for deploying infrastructure" - type = string -} diff --git a/4-projects/business_unit_2/shared/README.md b/4-projects/business_unit_2/shared/README.md index d35216266..1a3366eb9 100644 --- a/4-projects/business_unit_2/shared/README.md +++ b/4-projects/business_unit_2/shared/README.md @@ -5,14 +5,10 @@ |------|-------------|------|---------|:--------:| | 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}` | `string` | `null` | no | | alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | budget\_amount | The amount to use as the budget | `number` | `1000` | no | | default\_region | Default region to create resources where applicable. | `string` | `"us-central1"` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | | impersonate\_service\_account | Service account email of the account to impersonate to run gcloud build submit | `string` | n/a | yes | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | ## Outputs diff --git a/4-projects/business_unit_2/shared/example_infra_pipeline.tf b/4-projects/business_unit_2/shared/example_infra_pipeline.tf index ab93fbe91..a0ded8c1d 100644 --- a/4-projects/business_unit_2/shared/example_infra_pipeline.tf +++ b/4-projects/business_unit_2/shared/example_infra_pipeline.tf @@ -16,14 +16,14 @@ module "app_infra_cloudbuild_project" { source = "../../modules/single_project" - org_id = var.org_id - billing_account = var.billing_account - folder_id = data.google_active_folder.common.name + org_id = local.org_id + billing_account = local.billing_account + folder_id = local.common_folder_name environment = "common" alert_spent_percents = var.alert_spent_percents alert_pubsub_topic = var.alert_pubsub_topic budget_amount = var.budget_amount - project_prefix = var.project_prefix + project_prefix = local.project_prefix activate_apis = [ "cloudbuild.googleapis.com", "sourcerepo.googleapis.com", @@ -45,8 +45,8 @@ module "infra_pipelines" { source = "../../modules/infra_pipelines" impersonate_service_account = var.impersonate_service_account cloudbuild_project_id = module.app_infra_cloudbuild_project.project_id - project_prefix = var.project_prefix - billing_account = var.billing_account + project_prefix = local.project_prefix + billing_account = local.billing_account default_region = var.default_region bucket_region = var.default_region app_infra_repos = ["bu2-example-app"] diff --git a/4-projects/business_unit_2/shared/folder.tf b/4-projects/business_unit_2/shared/folder.tf deleted file mode 100644 index 7e7311605..000000000 --- a/4-projects/business_unit_2/shared/folder.tf +++ /dev/null @@ -1,20 +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. - */ - -data "google_active_folder" "common" { - display_name = "${var.folder_prefix}-common" - parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} diff --git a/4-projects/business_unit_2/shared/main.tf b/4-projects/business_unit_2/shared/main.tf new file mode 100644 index 000000000..26ebb3071 --- /dev/null +++ b/4-projects/business_unit_2/shared/main.tf @@ -0,0 +1,44 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder + parent = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + common_folder_name = data.terraform_remote_state.org.outputs.common_folder_name + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } +} + +data "terraform_remote_state" "org" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/org/state" + } +} diff --git a/4-projects/business_unit_2/shared/variables.tf b/4-projects/business_unit_2/shared/variables.tf index 9f2bdae72..8e7f6c569 100644 --- a/4-projects/business_unit_2/shared/variables.tf +++ b/4-projects/business_unit_2/shared/variables.tf @@ -25,22 +25,6 @@ variable "impersonate_service_account" { type = string } -variable "org_id" { - description = "The organization id for the associated services" - type = string -} - -variable "billing_account" { - description = "The ID of the billing account to associated this project with" - type = string -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - variable "alert_spent_percents" { description = "A list of percentages of the budget to alert on when threshold is exceeded" type = list(number) @@ -59,14 +43,7 @@ variable "budget_amount" { default = 1000 } -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." type = string - default = "prj" } diff --git a/4-projects/common.auto.example.tfvars b/4-projects/common.auto.example.tfvars index f06d5f46e..6ed9bbe23 100644 --- a/4-projects/common.auto.example.tfvars +++ b/4-projects/common.auto.example.tfvars @@ -14,10 +14,4 @@ * limitations under the License. */ -billing_account = "000000-000000-000000" - -org_id = "000000000000" - -// Optional - for an organization with existing projects or for development/validation. -// Must be the same value used in previous steps. -//parent_folder = "01234567890" +backend_bucket = "" diff --git a/4-projects/development.auto.example.tfvars b/4-projects/development.auto.example.tfvars index e440bc16b..f63111f83 100644 --- a/4-projects/development.auto.example.tfvars +++ b/4-projects/development.auto.example.tfvars @@ -14,6 +14,5 @@ * limitations under the License. */ -perimeter_name = "sp_d_shared_restricted_default_perimeter_????" - -//enable_hub_and_spoke = true +location_kms = "us" +location_gcs = "US" diff --git a/4-projects/modules/base_env/README.md b/4-projects/modules/base_env/README.md index 2e56c7fe6..85eb10add 100644 --- a/4-projects/modules/base_env/README.md +++ b/4-projects/modules/base_env/README.md @@ -3,18 +3,14 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| access\_context\_manager\_policy\_id | The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format="value(name)"`. | `string` | n/a | yes | | 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}` | `string` | `null` | no | | alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded | `list(number)` |
[
0.5,
0.75,
0.9,
0.95
]
| no | -| app\_infra\_pipeline\_cloudbuild\_sa | Cloud Build SA used for deploying infrastructure | `string` | n/a | yes | -| billing\_account | The ID of the billing account to associated this project with | `string` | n/a | yes | +| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | | budget\_amount | The amount to use as the budget | `number` | `1000` | no | | business\_code | The business code (ex. bu1). | `string` | n/a | yes | | business\_unit | The business (ex. business\_unit\_1). | `string` | n/a | yes | -| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no | | env | The environment to prepare (ex. development). | `string` | n/a | yes | | firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls. | `bool` | `true` | no | -| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | | gcs\_bucket\_prefix | Name prefix to be used for GCS Bucket | `string` | `"cmek-encrypted-bucket"` | no | | key\_name | Name to be used for KMS Key | `string` | `"crypto-key-example"` | no | | key\_rotation\_period | Rotation period in seconds to be used for KMS Key | `string` | `"7776000s"` | no | @@ -22,11 +18,7 @@ | location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `"US"` | no | | location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `"us"` | no | | optional\_fw\_rules\_enabled | Toggle creation of optional firewall rules: IAP SSH, IAP RDP and Internal & Global load balancing health check and load balancing IP ranges. | `bool` | `false` | no | -| org\_id | The organization id for the associated services | `string` | n/a | yes | -| parent\_folder | 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. Must be the same value used in previous step. | `string` | `""` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | -| perimeter\_name | Access context manager service perimeter name to attach the restricted svpc project. | `string` | n/a | yes | -| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no | | secrets\_prj\_suffix | Name suffix to use for secrets project created. | `string` | `"env-secrets"` | no | | windows\_activation\_enabled | Enable Windows license activation for Windows workloads. | `bool` | `false` | no | @@ -34,6 +26,7 @@ | Name | Description | |------|-------------| +| access\_context\_manager\_policy\_id | Access Context Manager Policy ID. | | base\_shared\_vpc\_project | Project sample base project. | | base\_shared\_vpc\_project\_sa | Project sample base project SA. | | bucket | The created storage bucket | @@ -47,5 +40,6 @@ | restricted\_enabled\_apis | Activated APIs. | | restricted\_shared\_vpc\_project | Project sample restricted project id. | | restricted\_shared\_vpc\_project\_number | Project sample restricted project. | +| vpc\_service\_control\_perimeter\_name | VPC Service Control name. | diff --git a/4-projects/modules/base_env/example_base_shared_vpc_project.tf b/4-projects/modules/base_env/example_base_shared_vpc_project.tf index da3af98bf..178693a4a 100644 --- a/4-projects/modules/base_env/example_base_shared_vpc_project.tf +++ b/4-projects/modules/base_env/example_base_shared_vpc_project.tf @@ -15,20 +15,22 @@ */ module "base_shared_vpc_project" { - source = "../single_project" - org_id = var.org_id - billing_account = var.billing_account - folder_id = data.google_active_folder.env.name - environment = var.env - vpc_type = "base" - alert_spent_percents = var.alert_spent_percents - alert_pubsub_topic = var.alert_pubsub_topic - budget_amount = var.budget_amount - project_prefix = var.project_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke - sa_roles = ["roles/editor"] - enable_cloudbuild_deploy = true - cloudbuild_sa = var.app_infra_pipeline_cloudbuild_sa + source = "../single_project" + + org_id = local.org_id + billing_account = local.billing_account + folder_id = local.env_folder_name + environment = var.env + vpc_type = "base" + shared_vpc_host_project_id = local.base_host_project_id + shared_vpc_subnets = local.base_subnets_self_links + alert_spent_percents = var.alert_spent_percents + alert_pubsub_topic = var.alert_pubsub_topic + budget_amount = var.budget_amount + project_prefix = local.project_prefix + sa_roles = ["roles/editor"] + enable_cloudbuild_deploy = true + cloudbuild_sa = local.app_infra_pipeline_cloudbuild_sa activate_apis = [ "iam.googleapis.com", "cloudresourcemanager.googleapis.com" diff --git a/4-projects/modules/base_env/example_floating_project.tf b/4-projects/modules/base_env/example_floating_project.tf index 305d816e4..35d2fc233 100644 --- a/4-projects/modules/base_env/example_floating_project.tf +++ b/4-projects/modules/base_env/example_floating_project.tf @@ -15,15 +15,16 @@ */ module "floating_project" { - source = "../single_project" - org_id = var.org_id - billing_account = var.billing_account - folder_id = data.google_active_folder.env.name + source = "../single_project" + + org_id = local.org_id + billing_account = local.billing_account + folder_id = local.env_folder_name environment = var.env alert_spent_percents = var.alert_spent_percents alert_pubsub_topic = var.alert_pubsub_topic budget_amount = var.budget_amount - project_prefix = var.project_prefix + project_prefix = local.project_prefix # Metadata project_suffix = "sample-floating" diff --git a/4-projects/modules/base_env/example_peering_project.tf b/4-projects/modules/base_env/example_peering_project.tf index 9e8af9158..6d8f3d1ab 100644 --- a/4-projects/modules/base_env/example_peering_project.tf +++ b/4-projects/modules/base_env/example_peering_project.tf @@ -15,17 +15,7 @@ */ locals { - shared_vpc_mode = var.enable_hub_and_spoke ? "-spoke" : "" - env_code = substr(var.env, 0, 1) -} - -data "google_projects" "projects" { - filter = "parent.id:${split("/", data.google_active_folder.env.name)[1]} labels.application_name=base-shared-vpc-host labels.environment=${var.env} lifecycleState=ACTIVE" -} - -data "google_compute_network" "shared_vpc" { - name = "vpc-${local.env_code}-shared-base${local.shared_vpc_mode}" - project = data.google_projects.projects.projects[0].project_id + env_code = substr(var.env, 0, 1) } data "google_netblock_ip_ranges" "legacy_health_checkers" { @@ -41,12 +31,13 @@ data "google_netblock_ip_ranges" "iap_forwarders" { } module "peering_project" { - source = "../single_project" - org_id = var.org_id - billing_account = var.billing_account - folder_id = data.google_active_folder.env.name + source = "../single_project" + + org_id = local.org_id + billing_account = local.billing_account + folder_id = local.env_folder_name environment = var.env - project_prefix = var.project_prefix + project_prefix = local.project_prefix # Metadata project_suffix = "sample-peering" @@ -72,7 +63,7 @@ module "peering" { version = "~> 5.0" prefix = "${var.business_code}-${local.env_code}" local_network = module.peering_network.network_self_link - peer_network = data.google_compute_network.shared_vpc.self_link + peer_network = local.base_network_self_link module_depends_on = var.peering_module_depends_on } diff --git a/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf b/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf index 1f40e3929..2894b149c 100644 --- a/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf +++ b/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf @@ -15,21 +15,24 @@ */ module "restricted_shared_vpc_project" { - source = "../single_project" - org_id = var.org_id - billing_account = var.billing_account - folder_id = data.google_active_folder.env.name - environment = var.env - vpc_type = "restricted" - alert_spent_percents = var.alert_spent_percents - alert_pubsub_topic = var.alert_pubsub_topic - budget_amount = var.budget_amount - project_prefix = var.project_prefix - enable_hub_and_spoke = var.enable_hub_and_spoke + source = "../single_project" + + org_id = local.org_id + billing_account = local.billing_account + folder_id = local.env_folder_name + environment = var.env + vpc_type = "restricted" + shared_vpc_host_project_id = local.restricted_host_project_id + shared_vpc_subnets = local.restricted_subnets_self_links + alert_spent_percents = var.alert_spent_percents + alert_pubsub_topic = var.alert_pubsub_topic + budget_amount = var.budget_amount + project_prefix = local.project_prefix + activate_apis = ["accesscontextmanager.googleapis.com"] vpc_service_control_attach_enabled = "true" - vpc_service_control_perimeter_name = "accessPolicies/${var.access_context_manager_policy_id}/servicePerimeters/${var.perimeter_name}" + vpc_service_control_perimeter_name = "accessPolicies/${local.access_context_manager_policy_id}/servicePerimeters/${local.perimeter_name}" # Metadata project_suffix = "sample-restrict" diff --git a/4-projects/modules/base_env/example_storage_cmek.tf b/4-projects/modules/base_env/example_storage_cmek.tf index 152185f13..e5d431843 100644 --- a/4-projects/modules/base_env/example_storage_cmek.tf +++ b/4-projects/modules/base_env/example_storage_cmek.tf @@ -15,16 +15,17 @@ */ module "env_secrets_project" { - source = "../single_project" - org_id = var.org_id - billing_account = var.billing_account - folder_id = data.google_active_folder.env.name + source = "../single_project" + + org_id = local.org_id + billing_account = local.billing_account + folder_id = local.env_folder_name environment = var.env alert_spent_percents = var.alert_spent_percents alert_pubsub_topic = var.alert_pubsub_topic budget_amount = var.budget_amount project_suffix = var.secrets_prj_suffix - project_prefix = var.project_prefix + project_prefix = local.project_prefix activate_apis = ["logging.googleapis.com", "secretmanager.googleapis.com", "cloudkms.googleapis.com"] diff --git a/4-projects/modules/base_env/folder.tf b/4-projects/modules/base_env/folder.tf deleted file mode 100644 index 2b81adfe8..000000000 --- a/4-projects/modules/base_env/folder.tf +++ /dev/null @@ -1,21 +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. - */ - -data "google_active_folder" "env" { - display_name = "${var.folder_prefix}-${var.env}" - parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}" -} - diff --git a/4-projects/modules/base_env/main.tf b/4-projects/modules/base_env/main.tf new file mode 100644 index 000000000..692cde451 --- /dev/null +++ b/4-projects/modules/base_env/main.tf @@ -0,0 +1,70 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id + parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder + parent = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id + billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix + folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix + perimeter_name = data.terraform_remote_state.network_env.outputs.restricted_service_perimeter_name + base_network_self_link = data.terraform_remote_state.network_env.outputs.base_network_self_link + base_subnets_self_links = data.terraform_remote_state.network_env.outputs.base_subnets_self_links + base_host_project_id = data.terraform_remote_state.network_env.outputs.base_host_project_id + restricted_host_project_id = data.terraform_remote_state.network_env.outputs.restricted_host_project_id + restricted_subnets_self_links = data.terraform_remote_state.network_env.outputs.restricted_subnets_self_links + access_context_manager_policy_id = data.terraform_remote_state.network_env.outputs.access_context_manager_policy_id + env_folder_name = data.terraform_remote_state.environments_env.outputs.env_folder + app_infra_pipeline_cloudbuild_sa = data.terraform_remote_state.business_unit_shared.outputs.cloudbuild_sa +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/bootstrap/state" + } +} + +data "terraform_remote_state" "network_env" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/networks/${var.env}" + } +} + +data "terraform_remote_state" "environments_env" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/environments/${var.env}" + } +} + +data "terraform_remote_state" "business_unit_shared" { + backend = "gcs" + + config = { + bucket = var.backend_bucket + prefix = "terraform/projects/${var.business_unit}/shared" + } +} diff --git a/4-projects/modules/base_env/outputs.tf b/4-projects/modules/base_env/outputs.tf index 52a1786b6..692a71a6b 100644 --- a/4-projects/modules/base_env/outputs.tf +++ b/4-projects/modules/base_env/outputs.tf @@ -49,6 +49,16 @@ output "restricted_shared_vpc_project_number" { value = module.restricted_shared_vpc_project.project_number } +output "vpc_service_control_perimeter_name" { + description = "VPC Service Control name." + value = local.perimeter_name +} + +output "access_context_manager_policy_id" { + description = "Access Context Manager Policy ID." + value = local.access_context_manager_policy_id +} + output "restricted_enabled_apis" { description = "Activated APIs." value = module.restricted_shared_vpc_project.enabled_apis diff --git a/4-projects/modules/base_env/variables.tf b/4-projects/modules/base_env/variables.tf index a8940c757..c904ae818 100644 --- a/4-projects/modules/base_env/variables.tf +++ b/4-projects/modules/base_env/variables.tf @@ -29,32 +29,6 @@ variable "env" { type = string } -variable "org_id" { - description = "The organization id for the associated services" - type = string -} - -variable "billing_account" { - description = "The ID of the billing account to associated this project with" - type = string -} - -variable "access_context_manager_policy_id" { - type = string - description = "The ID of the access context manager policy the perimeter lies in. Can be obtained by running `gcloud access-context-manager policies list --organization YOUR_ORGANIZATION_ID --format=\"value(name)\"`." -} - -variable "parent_folder" { - 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. Must be the same value used in previous step." - type = string - default = "" -} - -variable "perimeter_name" { - description = "Access context manager service perimeter name to attach the restricted svpc project." - type = string -} - variable "peering_module_depends_on" { description = "List of modules or resources peering module depends on." type = list(any) @@ -97,29 +71,6 @@ variable "budget_amount" { default = 1000 } -variable "project_prefix" { - description = "Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters." - type = string - default = "prj" -} - -variable "folder_prefix" { - description = "Name prefix to use for folders created. Should be the same in all steps." - type = string - default = "fldr" -} - -variable "enable_hub_and_spoke" { - description = "Enable Hub-and-Spoke architecture." - type = bool - default = false -} - -variable "app_infra_pipeline_cloudbuild_sa" { - description = "Cloud Build SA used for deploying infrastructure" - type = string -} - variable "secrets_prj_suffix" { description = "Name suffix to use for secrets project created." type = string @@ -161,3 +112,8 @@ variable "gcs_bucket_prefix" { type = string default = "cmek-encrypted-bucket" } + +variable "backend_bucket" { + description = "Backend bucket to load remote state information from previous steps." + type = string +} diff --git a/4-projects/modules/single_project/README.md b/4-projects/modules/single_project/README.md index b8453dfa6..14f4c8fb6 100644 --- a/4-projects/modules/single_project/README.md +++ b/4-projects/modules/single_project/README.md @@ -22,6 +22,8 @@ | project\_suffix | The name of the GCP project. Max 16 characters with 3 character business unit code. | `string` | n/a | yes | | sa\_roles | A list of roles to give the Service Account for the project (defaults to none) | `list(string)` | `[]` | no | | secondary\_contact | The secondary email contact for the project | `string` | `""` | no | +| shared\_vpc\_host\_project\_id | Shared VPC host project ID | `string` | `""` | no | +| shared\_vpc\_subnets | List of the shared vpc subnets self links. | `list(string)` | `[]` | no | | vpc\_service\_control\_attach\_enabled | Whether the project will be attached to a VPC Service Control Perimeter | `bool` | `false` | no | | vpc\_service\_control\_perimeter\_name | The name of a VPC Service Control Perimeter to add the created project to | `string` | `null` | no | | vpc\_type | The type of VPC to attach the project to. Possible options are base or restricted. | `string` | `""` | no | diff --git a/4-projects/modules/single_project/data.tf b/4-projects/modules/single_project/data.tf deleted file mode 100644 index bce53ed9d..000000000 --- a/4-projects/modules/single_project/data.tf +++ /dev/null @@ -1,26 +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. - */ - -data "google_projects" "projects" { - count = var.vpc_type == "" ? 0 : 1 - filter = "parent.id:${split("/", var.folder_id)[1]} labels.application_name=${var.vpc_type}-shared-vpc-host labels.environment=${var.environment} lifecycleState=ACTIVE" -} - -data "google_compute_network" "shared_vpc" { - count = var.vpc_type == "" ? 0 : 1 - name = "vpc-${local.env_code}-shared-${var.vpc_type}${local.shared_vpc_mode}" - project = data.google_projects.projects[0].projects[0].project_id -} diff --git a/4-projects/modules/single_project/main.tf b/4-projects/modules/single_project/main.tf index 34019cd6a..5f7712d36 100644 --- a/4-projects/modules/single_project/main.tf +++ b/4-projects/modules/single_project/main.tf @@ -29,8 +29,8 @@ module "project" { billing_account = var.billing_account folder_id = var.folder_id - svpc_host_project_id = var.vpc_type == "" ? "" : data.google_compute_network.shared_vpc[0].project - shared_vpc_subnets = var.vpc_type == "" ? [] : data.google_compute_network.shared_vpc[0].subnetworks_self_links # Optional: To enable subnetting, replace to "module.networking_project.subnetwork_self_link" + svpc_host_project_id = var.shared_vpc_host_project_id + shared_vpc_subnets = var.shared_vpc_subnets # Optional: To enable subnetting, replace to "module.networking_project.subnetwork_self_link" vpc_service_control_attach_enabled = var.vpc_service_control_attach_enabled vpc_service_control_perimeter_name = var.vpc_service_control_perimeter_name diff --git a/4-projects/modules/single_project/variables.tf b/4-projects/modules/single_project/variables.tf index 0c07cf986..1adbb7192 100644 --- a/4-projects/modules/single_project/variables.tf +++ b/4-projects/modules/single_project/variables.tf @@ -78,6 +78,18 @@ variable "vpc_type" { default = "" } +variable "shared_vpc_host_project_id" { + description = "Shared VPC host project ID" + type = string + default = "" +} + +variable "shared_vpc_subnets" { + description = "List of the shared vpc subnets self links." + type = list(string) + default = [] +} + variable "vpc_service_control_attach_enabled" { description = "Whether the project will be attached to a VPC Service Control Perimeter" type = bool diff --git a/4-projects/non-production.auto.example.tfvars b/4-projects/non-production.auto.example.tfvars index fb4c2af42..f63111f83 100644 --- a/4-projects/non-production.auto.example.tfvars +++ b/4-projects/non-production.auto.example.tfvars @@ -14,6 +14,5 @@ * limitations under the License. */ -perimeter_name = "sp_n_shared_restricted_default_perimeter_????" - -//enable_hub_and_spoke = true +location_kms = "us" +location_gcs = "US" diff --git a/4-projects/production.auto.example.tfvars b/4-projects/production.auto.example.tfvars index 5444ff2d3..f63111f83 100644 --- a/4-projects/production.auto.example.tfvars +++ b/4-projects/production.auto.example.tfvars @@ -14,6 +14,5 @@ * limitations under the License. */ -perimeter_name = "sp_p_shared_restricted_default_perimeter_????" - -//enable_hub_and_spoke = true +location_kms = "us" +location_gcs = "US" diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index 1d5490f72..131ef8580 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -44,7 +44,7 @@ steps: - id: create-org name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', './test/disable_tf_files.sh --org && cft test run TestOrg --stage init --verbose --test-dir /workspace/test/integration'] + args: ['/bin/bash', '-c', 'cft test run TestOrg --stage init --verbose --test-dir /workspace/test/integration'] - id: converge-org name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' @@ -56,7 +56,7 @@ steps: - id: create-envs name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' - args: ['/bin/bash', '-c', './test/disable_tf_files.sh --envs && cft test run TestEnvs --stage init --verbose --test-dir /workspace/test/integration'] + args: ['/bin/bash', '-c', 'cft test run TestEnvs --stage init --verbose --test-dir /workspace/test/integration'] - id: converge-envs name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' @@ -90,6 +90,18 @@ steps: name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'cft test run TestNetworks --stage verify --verbose --test-dir /workspace/test/integration'] +- id: create-projects-shared + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', './test/disable_tf_files.sh --projectsshared && cft test run TestProjectsShared --stage init --verbose --test-dir /workspace/test/integration'] + +- id: converge-projects-shared + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestProjectsShared --stage apply --verbose --test-dir /workspace/test/integration'] + +- id: verify-projects-shared + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestProjectsShared --stage verify --verbose --test-dir /workspace/test/integration'] + - id: create-projects name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', './test/disable_tf_files.sh --projects && cft test run TestProjects --stage init --verbose --test-dir /workspace/test/integration'] @@ -122,6 +134,10 @@ steps: name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'cft test run TestProjects --stage destroy --verbose --test-dir /workspace/test/integration'] +- id: destroy-projects-shared + name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' + args: ['/bin/bash', '-c', 'cft test run TestProjectsShared --stage destroy --verbose --test-dir /workspace/test/integration'] + - id: destroy-networks name: 'gcr.io/cloud-foundation-cicd/$_DOCKER_IMAGE_DEVELOPER_TOOLS:$_DOCKER_TAG_VERSION_DEVELOPER_TOOLS' args: ['/bin/bash', '-c', 'cft test run TestNetworks --stage destroy --verbose --test-dir /workspace/test/integration'] diff --git a/test/disable_tf_files.sh b/test/disable_tf_files.sh index e14cece51..d00d48dff 100755 --- a/test/disable_tf_files.sh +++ b/test/disable_tf_files.sh @@ -16,18 +16,6 @@ set -e -function org(){ - # disable backend configs in main module - mv 1-org/envs/shared/backend.tf 1-org/envs/shared/backend.tf.disabled -} - -function envs(){ - # disable backend configs in main module - mv 2-environments/envs/development/backend.tf 2-environments/envs/development/backend.tf.disabled - mv 2-environments/envs/non-production/backend.tf 2-environments/envs/non-production/backend.tf.disabled - mv 2-environments/envs/production/backend.tf 2-environments/envs/production/backend.tf.disabled -} - function networks(){ # shellcheck disable=SC2154 @@ -37,11 +25,6 @@ function networks(){ network_dir="3-networks-dual-svpc" fi - # disable backend configs in main module - mv $network_dir/envs/development/backend.tf $network_dir/envs/development/backend.tf.disabled - mv $network_dir/envs/non-production/backend.tf $network_dir/envs/non-production/backend.tf.disabled - mv $network_dir/envs/production/backend.tf $network_dir/envs/production/backend.tf.disabled - # 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/non-production/access_context.auto.tfvars $network_dir/envs/non-production/access_context.auto.tfvars.disabled @@ -61,9 +44,6 @@ function shared(){ network_dir="3-networks-dual-svpc" fi - # disable backend configs in main module - mv $network_dir/envs/shared/backend.tf $network_dir/envs/shared/backend.tf.disabled - # 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 @@ -74,35 +54,17 @@ function shared(){ mv $network_dir/envs/shared/shared.auto.tfvars $network_dir/envs/shared/shared.auto.tfvars.disabled } -function projects(){ - # disable backend configs in main module - mv 4-projects/business_unit_1/development/backend.tf 4-projects/business_unit_1/development/backend.tf.disabled - mv 4-projects/business_unit_1/non-production/backend.tf 4-projects/business_unit_1/non-production/backend.tf.disabled - mv 4-projects/business_unit_1/production/backend.tf 4-projects/business_unit_1/production/backend.tf.disabled - mv 4-projects/business_unit_1/shared/backend.tf 4-projects/business_unit_1/shared/backend.tf.disabled - mv 4-projects/business_unit_2/development/backend.tf 4-projects/business_unit_2/development/backend.tf.disabled - mv 4-projects/business_unit_2/non-production/backend.tf 4-projects/business_unit_2/non-production/backend.tf.disabled - mv 4-projects/business_unit_2/production/backend.tf 4-projects/business_unit_2/production/backend.tf.disabled - mv 4-projects/business_unit_2/shared/backend.tf 4-projects/business_unit_2/shared/backend.tf.disabled +function projectsshared(){ + # disable shared.auto.tfvars + mv 4-projects/business_unit_1/shared/shared.auto.tfvars 4-projects/business_unit_1/shared/shared.auto.tfvars.disabled + mv 4-projects/business_unit_2/shared/shared.auto.tfvars 4-projects/business_unit_2/shared/shared.auto.tfvars.disabled - # disable access_context.auto.tfvars in main module - mv 4-projects/business_unit_1/development/access_context.auto.tfvars 4-projects/business_unit_1/development/access_context.auto.tfvars.disabled - mv 4-projects/business_unit_1/non-production/access_context.auto.tfvars 4-projects/business_unit_1/non-production/access_context.auto.tfvars.disabled - mv 4-projects/business_unit_1/production/access_context.auto.tfvars 4-projects/business_unit_1/production/access_context.auto.tfvars.disabled - mv 4-projects/business_unit_2/development/access_context.auto.tfvars 4-projects/business_unit_2/development/access_context.auto.tfvars.disabled - mv 4-projects/business_unit_2/non-production/access_context.auto.tfvars 4-projects/business_unit_2/non-production/access_context.auto.tfvars.disabled - mv 4-projects/business_unit_2/production/access_context.auto.tfvars 4-projects/business_unit_2/production/access_context.auto.tfvars.disabled - - # disable business_unit_1.auto.tfvars in main module - mv 4-projects/business_unit_1/development/business_unit_1.auto.tfvars 4-projects/business_unit_1/development/business_unit_1.auto.tfvars.disabled - mv 4-projects/business_unit_1/non-production/business_unit_1.auto.tfvars 4-projects/business_unit_1/non-production/business_unit_1.auto.tfvars.disabled - mv 4-projects/business_unit_1/production/business_unit_1.auto.tfvars 4-projects/business_unit_1/production/business_unit_1.auto.tfvars.disabled - - # disable business_unit_2.auto.tfvars in main module - mv 4-projects/business_unit_2/development/business_unit_2.auto.tfvars 4-projects/business_unit_2/development/business_unit_2.auto.tfvars.disabled - mv 4-projects/business_unit_2/non-production/business_unit_2.auto.tfvars 4-projects/business_unit_2/non-production/business_unit_2.auto.tfvars.disabled - mv 4-projects/business_unit_2/production/business_unit_2.auto.tfvars 4-projects/business_unit_2/production/business_unit_2.auto.tfvars.disabled + # disable common.auto.tfvars + mv 4-projects/business_unit_1/shared/common.auto.tfvars 4-projects/business_unit_1/shared/common.auto.tfvars.disabled + mv 4-projects/business_unit_2/shared/common.auto.tfvars 4-projects/business_unit_2/shared/common.auto.tfvars.disabled +} +function projects(){ # disable ENVS.auto.tfvars in main module mv 4-projects/business_unit_1/development/development.auto.tfvars 4-projects/business_unit_1/development/development.auto.tfvars.disabled mv 4-projects/business_unit_2/development/development.auto.tfvars 4-projects/business_unit_2/development/development.auto.tfvars.disabled @@ -110,19 +72,14 @@ function projects(){ mv 4-projects/business_unit_2/non-production/non-production.auto.tfvars 4-projects/business_unit_2/non-production/non-production.auto.tfvars.disabled mv 4-projects/business_unit_1/production/production.auto.tfvars 4-projects/business_unit_1/production/production.auto.tfvars.disabled mv 4-projects/business_unit_2/production/production.auto.tfvars 4-projects/business_unit_2/production/production.auto.tfvars.disabled - mv 4-projects/business_unit_1/shared/shared.auto.tfvars 4-projects/business_unit_1/shared/shared.auto.tfvars.disabled - mv 4-projects/business_unit_2/shared/shared.auto.tfvars 4-projects/business_unit_2/shared/shared.auto.tfvars.disabled # disable common.auto.tfvars in main module mv 4-projects/business_unit_1/development/common.auto.tfvars 4-projects/business_unit_1/development/common.auto.tfvars.disabled mv 4-projects/business_unit_1/non-production/common.auto.tfvars 4-projects/business_unit_1/non-production/common.auto.tfvars.disabled mv 4-projects/business_unit_1/production/common.auto.tfvars 4-projects/business_unit_1/production/common.auto.tfvars.disabled - mv 4-projects/business_unit_1/shared/common.auto.tfvars 4-projects/business_unit_1/shared/common.auto.tfvars.disabled mv 4-projects/business_unit_2/development/common.auto.tfvars 4-projects/business_unit_2/development/common.auto.tfvars.disabled mv 4-projects/business_unit_2/non-production/common.auto.tfvars 4-projects/business_unit_2/non-production/common.auto.tfvars.disabled mv 4-projects/business_unit_2/production/common.auto.tfvars 4-projects/business_unit_2/production/common.auto.tfvars.disabled - mv 4-projects/business_unit_2/shared/common.auto.tfvars 4-projects/business_unit_2/shared/common.auto.tfvars.disabled - } function appinfra(){ @@ -155,18 +112,14 @@ do shared shift ;; - -o|--org) - org - shift - ;; - -e|--envs) - envs - shift - ;; -a|--appinfra) appinfra shift ;; + -d|--projectsshared) + projectsshared + shift + ;; -p|--projects) projects shift diff --git a/test/integration/bootstrap/bootstrap_test.go b/test/integration/bootstrap/bootstrap_test.go index a280cdc9c..f9a8dc0f1 100644 --- a/test/integration/bootstrap/bootstrap_test.go +++ b/test/integration/bootstrap/bootstrap_test.go @@ -16,6 +16,9 @@ package bootstrap import ( "fmt" + "os" + "os/exec" + "path" "testing" "time" @@ -24,10 +27,23 @@ import ( "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" ) +// fileExists check if a give file exists +func fileExists(filePath string) (bool, error) { + _, err := os.Stat(filePath) + if err == nil { + return true, nil + } + if os.IsNotExist(err) { + return false, nil + } + return false, err +} + func TestBootstrap(t *testing.T) { vars := map[string]interface{}{ @@ -76,10 +92,9 @@ func TestBootstrap(t *testing.T) { "accesscontextmanager.googleapis.com", } - orgID := utils.ValFromEnv(t, "TF_VAR_org_id") - bootstrap.DefineApply( func(assert *assert.Assertions) { + // check APIs projectID := bootstrap.GetTFSetupStringOutput("project_id") for _, api := range []string{ "cloudresourcemanager.googleapis.com", @@ -100,6 +115,25 @@ func TestBootstrap(t *testing.T) { } bootstrap.DefaultApply(assert) + + // configure options to push state to GCS bucket + tempOptions := bootstrap.GetTFOptions() + tempOptions.BackendConfig = map[string]interface{}{ + "bucket": bootstrap.GetStringOutput("gcs_bucket_tfstate"), + } + tempOptions.MigrateState = true + // create backend file + cwd, err := os.Getwd() + require.NoError(t, err) + destFile := path.Join(cwd, "../../../0-bootstrap/backend.tf") + fExists, err2 := fileExists(destFile) + require.NoError(t, err2) + if !fExists { + srcFile := path.Join(cwd, "../../../0-bootstrap/backend.tf.example") + _, err3 := exec.Command("cp", srcFile, destFile).CombinedOutput() + require.NoError(t, err3) + } + terraform.Init(t, tempOptions) }) bootstrap.DefineVerify( @@ -195,6 +229,7 @@ func TestBootstrap(t *testing.T) { iamFilter := fmt.Sprintf("bindings.members:'serviceAccount:%s'", terraformSAEmail) iamOpts := gcloud.WithCommonArgs([]string{"--flatten", "bindings", "--filter", iamFilter, "--format", "json"}) + orgID := bootstrap.GetTFSetupStringOutput("org_id") orgIamPolicyRoles := gcloud.Run(t, fmt.Sprintf("organizations get-iam-policy %s", orgID), iamOpts).Array() listRoles := testutils.GetResultFieldStrSlice(orgIamPolicyRoles, "bindings.role") if len(sa.orgRoles) == 0 { @@ -204,5 +239,27 @@ func TestBootstrap(t *testing.T) { } } }) + + bootstrap.DefineTeardown(func(assert *assert.Assertions) { + // configure options to pull state from GCS bucket + cwd, err := os.Getwd() + require.NoError(t, err) + statePath := path.Join(cwd, "../../../0-bootstrap/local_backend.tfstate") + tempOptions := bootstrap.GetTFOptions() + tempOptions.BackendConfig = map[string]interface{}{ + "path": statePath, + } + tempOptions.MigrateState = true + // remove backend file + backendFile := path.Join(cwd, "../../../0-bootstrap/backend.tf") + fExists, err2 := fileExists(backendFile) + require.NoError(t, err2) + if fExists { + _, err3 := exec.Command("rm", backendFile).CombinedOutput() + require.NoError(t, err3) + } + terraform.Init(t, tempOptions) + bootstrap.DefaultTeardown(assert) + }) bootstrap.Test() } diff --git a/test/integration/envs/envs_test.go b/test/integration/envs/envs_test.go index 7255aea17..313c7359d 100644 --- a/test/integration/envs/envs_test.go +++ b/test/integration/envs/envs_test.go @@ -36,6 +36,18 @@ func TestEnvs(t *testing.T) { terraformSA := bootstrap.GetStringOutput("environment_step_terraform_service_account_email") utils.SetEnv(t, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", terraformSA) + backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") + monitoringWorkspaceUsers := bootstrap.GetTFSetupStringOutput("monitoring_workspace_users") + + vars := map[string]interface{}{ + "backend_bucket": backend_bucket, + "monitoring_workspace_users": monitoringWorkspaceUsers, + } + + backendConfig := map[string]interface{}{ + "bucket": backend_bucket, + } + for _, envName := range []string{ "development", "non-production", @@ -44,6 +56,8 @@ func TestEnvs(t *testing.T) { t.Run(envName, func(t *testing.T) { envs := tft.NewTFBlueprintTest(t, tft.WithTFDir(fmt.Sprintf("../../../2-environments/envs/%s", envName)), + tft.WithVars(vars), + tft.WithBackendConfig(backendConfig), ) envs.DefineVerify( func(assert *assert.Assertions) { @@ -64,7 +78,7 @@ func TestEnvs(t *testing.T) { { projectOutput: "monitoring_project_id", role: "roles/monitoring.editor", - group: "TF_VAR_group_email", + group: monitoringWorkspaceUsers, apis: []string{ "logging.googleapis.com", "monitoring.googleapis.com", @@ -115,9 +129,8 @@ func TestEnvs(t *testing.T) { if projectEnvOutput.role != "" { iamOpts := gcloud.WithCommonArgs([]string{"--flatten", "bindings", "--filter", fmt.Sprintf("bindings.role:%s", projectEnvOutput.role), "--format", "json"}) iamPolicy := gcloud.Run(t, fmt.Sprintf("projects get-iam-policy %s", projectID), iamOpts).Array()[0] - group := utils.ValFromEnv(t, projectEnvOutput.group) listMembers := utils.GetResultStrSlice(iamPolicy.Get("bindings.members").Array()) - assert.Contains(listMembers, fmt.Sprintf("group:%s", group), fmt.Sprintf("group %s should have role %s", group, projectEnvOutput.role)) + assert.Contains(listMembers, fmt.Sprintf("group:%s", projectEnvOutput.group), fmt.Sprintf("group %s should have role %s", projectEnvOutput.group, projectEnvOutput.role)) } } diff --git a/test/integration/go.mod b/test/integration/go.mod index 2a54bd43b..9fc390ca0 100644 --- a/test/integration/go.mod +++ b/test/integration/go.mod @@ -3,7 +3,7 @@ module github.com/terraform-google-modules/terraform-example-foundation/test/int go 1.17 require ( - github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.1.1-0.20220801181634-4ea786f947df + github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.1.1-0.20220802155302-a13ee7fb1c62 github.com/gruntwork-io/terratest v0.40.7 github.com/stretchr/testify v1.7.1 github.com/tidwall/gjson v1.12.1 diff --git a/test/integration/go.sum b/test/integration/go.sum index 7ea09d67f..031066e2e 100644 --- a/test/integration/go.sum +++ b/test/integration/go.sum @@ -65,8 +65,8 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.1.1-0.20220801181634-4ea786f947df h1:kFAGiw70ZfrF0fo2IGbOze4DHWoRAeI1ID8fliacmIc= -github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.1.1-0.20220801181634-4ea786f947df/go.mod h1:E655Ka0BfIYALBmqU9ZbemLk/nutxw4vU6wkLEjshSA= +github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.1.1-0.20220802155302-a13ee7fb1c62 h1:uDiVwwTc7caRf6k2+MBKf3Ia+Z9nWu9diaJQUN3oGdA= +github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test v0.1.1-0.20220802155302-a13ee7fb1c62/go.mod h1:E655Ka0BfIYALBmqU9ZbemLk/nutxw4vU6wkLEjshSA= github.com/GoogleContainerTools/kpt-functions-sdk/go v0.0.0-20220301220754-6964a09d6cd2/go.mod h1:lJYiqfBOl6AOiefK9kmkhinbffIysu+nnclOBwKEPlQ= github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= diff --git a/test/integration/networks/networks_test.go b/test/integration/networks/networks_test.go index c531633aa..92941cd9b 100644 --- a/test/integration/networks/networks_test.go +++ b/test/integration/networks/networks_test.go @@ -91,6 +91,11 @@ func TestNetworks(t *testing.T) { terraformSA := bootstrap.GetStringOutput("networks_step_terraform_service_account_email") utils.SetEnv(t, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", terraformSA) + backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") + backendConfig := map[string]interface{}{ + "bucket": backend_bucket, + } + restrictedServices := []string{ "bigquery.googleapis.com", "storage.googleapis.com", @@ -125,6 +130,7 @@ func TestNetworks(t *testing.T) { vars := map[string]interface{}{ "access_context_manager_policy_id": policyID, + "backend_bucket": backend_bucket, "terraform_service_account": terraformSA, } @@ -139,6 +145,7 @@ func TestNetworks(t *testing.T) { networks := tft.NewTFBlueprintTest(t, tft.WithTFDir(fmt.Sprintf(tfdDir, envName)), tft.WithVars(vars), + tft.WithBackendConfig(backendConfig), ) networks.DefineVerify( func(assert *assert.Assertions) { diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go index 919e8a7fe..08b92c70c 100644 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -16,6 +16,7 @@ package org import ( "fmt" + "strconv" "testing" "time" @@ -23,14 +24,11 @@ import ( "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/tft" "github.com/GoogleCloudPlatform/cloud-foundation-toolkit/infra/blueprint-test/pkg/utils" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/terraform-google-modules/terraform-example-foundation/test/integration/testutils" ) -func isHubAndSpoke(t *testing.T) bool { - return utils.ValFromEnv(t, "TF_VAR_example_foundations_mode") == "HubAndSpoke" -} - func TestOrg(t *testing.T) { bootstrap := tft.NewTFBlueprintTest(t, @@ -38,8 +36,17 @@ func TestOrg(t *testing.T) { ) networksTerraformSA := bootstrap.GetStringOutput("networks_step_terraform_service_account_email") + backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") + vars := map[string]interface{}{ "networks_step_terraform_service_account_email": networksTerraformSA, + "backend_bucket": backend_bucket, + "log_export_storage_force_destroy": "true", + "audit_logs_table_delete_contents_on_destroy": "true", + } + + backendConfig := map[string]interface{}{ + "bucket": backend_bucket, } // Configure impersonation for test execution @@ -49,6 +56,7 @@ func TestOrg(t *testing.T) { org := tft.NewTFBlueprintTest(t, tft.WithTFDir("../../../1-org/envs/shared"), tft.WithVars(vars), + tft.WithBackendConfig(backendConfig), ) org.DefineApply( @@ -130,7 +138,7 @@ func TestOrg(t *testing.T) { subscription := gcloud.Runf(t, "pubsub subscriptions describe %s --project %s", subscriptionName, sccProjectID) assert.Equal(subscriptionFullName, subscription.Get("name").String(), fmt.Sprintf("subscription %s should have been created", subscriptionName)) - orgID := utils.ValFromEnv(t, "TF_VAR_org_id") + orgID := bootstrap.GetTFSetupStringOutput("org_id") notificationName := org.GetStringOutput("scc_notification_name") notification := gcloud.Runf(t, "scc notifications describe %s --organization %s", notificationName, orgID) assert.Equal(topicFullName, notification.Get("pubsubTopic").String(), fmt.Sprintf("notification %s should use topic %s", notificationName, topicName)) @@ -203,7 +211,9 @@ func TestOrg(t *testing.T) { } // hub and spoke infrastructure - if isHubAndSpoke(t) { + enable_hub_and_spoke, err := strconv.ParseBool(bootstrap.GetTFSetupStringOutput("enable_hub_and_spoke")) + require.NoError(t, err) + if enable_hub_and_spoke { for _, hubAndSpokeProjectOutput := range []string{ "base_net_hub_project_id", "restricted_net_hub_project_id", diff --git a/test/integration/projects-shared/projects_shared_test.go b/test/integration/projects-shared/projects_shared_test.go new file mode 100644 index 000000000..4bfc14e19 --- /dev/null +++ b/test/integration/projects-shared/projects_shared_test.go @@ -0,0 +1,100 @@ +// 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. + +package projectsshared + +import ( + "fmt" + "testing" + + "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/stretchr/testify/assert" + + "github.com/terraform-google-modules/terraform-example-foundation/test/integration/testutils" +) + +func TestProjectsShared(t *testing.T) { + + bootstrap := tft.NewTFBlueprintTest(t, + tft.WithTFDir("../../../0-bootstrap"), + ) + + // Configure impersonation for test execution + terraformSA := bootstrap.GetStringOutput("projects_step_terraform_service_account_email") + utils.SetEnv(t, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", terraformSA) + + backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") + backendConfig := map[string]interface{}{ + "bucket": backend_bucket, + } + + var sharedApisEnabled = []string{ + "cloudbuild.googleapis.com", + "sourcerepo.googleapis.com", + "cloudkms.googleapis.com", + } + + for _, tts := range []struct { + name string + tfDir string + }{ + { + name: "bu1", + tfDir: "../../../4-projects/business_unit_1/shared", + }, + { + name: "bu2", + tfDir: "../../../4-projects/business_unit_2/shared", + }, + } { + t.Run(tts.name, func(t *testing.T) { + + sharedVars := map[string]interface{}{ + "backend_bucket": backend_bucket, + "impersonate_service_account": terraformSA, + } + + shared := tft.NewTFBlueprintTest(t, + tft.WithTFDir(tts.tfDir), + tft.WithVars(sharedVars), + tft.WithBackendConfig(backendConfig), + ) + + shared.DefineVerify( + func(assert *assert.Assertions) { + // perform default verification ensuring Terraform reports no additional changes on an applied blueprint + shared.DefaultVerify(assert) + + projectID := shared.GetStringOutput("cloudbuild_project_id") + prj := gcloud.Runf(t, "projects describe %s", projectID) + assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) + + 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") + + defaultRegion := shared.GetStringOutput("default_region") + tfRepo := shared.GetStringOutput("tf_runner_artifact_repo") + arOpts := gcloud.WithCommonArgs([]string{"--project", projectID, "--location", defaultRegion, "--format", "json"}) + artifactRegistry := gcloud.Run(t, fmt.Sprintf("artifacts repositories describe %s", tfRepo), arOpts) + repoName := fmt.Sprintf("projects/%s/locations/%s/repositories/%s", projectID, defaultRegion, tfRepo) + assert.Equal(repoName, artifactRegistry.Get("name").String(), fmt.Sprintf("artifact registry %s should exist", repoName)) + }) + shared.Test() + }) + + } +} diff --git a/test/integration/projects/projects_test.go b/test/integration/projects/projects_test.go index ebf211cbd..ac6be57ec 100644 --- a/test/integration/projects/projects_test.go +++ b/test/integration/projects/projects_test.go @@ -16,14 +16,12 @@ package projects import ( "fmt" - "strings" "testing" "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/stretchr/testify/assert" - "github.com/stretchr/testify/require" "github.com/terraform-google-modules/terraform-example-foundation/test/integration/testutils" ) @@ -56,9 +54,9 @@ func TestProjects(t *testing.T) { terraformSA := bootstrap.GetStringOutput("projects_step_terraform_service_account_email") utils.SetEnv(t, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", terraformSA) - var sharedCloudBuildSA = map[string]string{ - "bu1": "", - "bu2": "", + backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") + backendConfig := map[string]interface{}{ + "bucket": backend_bucket, } var restrictedApisEnabled = []string{ @@ -66,116 +64,52 @@ func TestProjects(t *testing.T) { "billingbudgets.googleapis.com", } - var sharedApisEnabled = []string{ - "cloudbuild.googleapis.com", - "sourcerepo.googleapis.com", - "cloudkms.googleapis.com", - } - - for _, tts := range []struct { - name string - tfDir string - }{ - { - name: "bu1", - tfDir: "../../../4-projects/business_unit_1/shared", - }, - { - name: "bu2", - tfDir: "../../../4-projects/business_unit_2/shared", - }, - } { - t.Run(tts.name, func(t *testing.T) { - - sharedVars := map[string]interface{}{ - "impersonate_service_account": terraformSA, - } - - shared := tft.NewTFBlueprintTest(t, - tft.WithTFDir(tts.tfDir), - tft.WithVars(sharedVars), - ) - - shared.DefineApply( - func(assert *assert.Assertions) { - // perform default apply of the blueprint - shared.DefaultApply(assert) - // save the value of the "cloudbuild_sa" to be used in the envs tests - sharedCloudBuildSA[tts.name] = shared.GetStringOutput("cloudbuild_sa") - }) - shared.DefineVerify( - func(assert *assert.Assertions) { - // perform default verification ensuring Terraform reports no additional changes on an applied blueprint - shared.DefaultVerify(assert) - // save the value of the "cloudbuild_sa" to be used in the envs tests - sharedCloudBuildSA[tts.name] = shared.GetStringOutput("cloudbuild_sa") - - projectID := shared.GetStringOutput("cloudbuild_project_id") - prj := gcloud.Runf(t, "projects describe %s", projectID) - assert.Equal("ACTIVE", prj.Get("lifecycleState").String(), fmt.Sprintf("project %s should be ACTIVE", projectID)) - - 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") - - defaultRegion := shared.GetStringOutput("default_region") - tfRepo := shared.GetStringOutput("tf_runner_artifact_repo") - arOpts := gcloud.WithCommonArgs([]string{"--project", projectID, "--location", defaultRegion, "--format", "json"}) - artifactRegistry := gcloud.Run(t, fmt.Sprintf("artifacts repositories describe %s", tfRepo), arOpts) - repoName := fmt.Sprintf("projects/%s/locations/%s/repositories/%s", projectID, defaultRegion, tfRepo) - assert.Equal(repoName, artifactRegistry.Get("name").String(), fmt.Sprintf("artifact registry %s should exist", repoName)) - }) - shared.Test() - }) - - } - for _, tt := range []struct { name string - tfDir string + baseDir string baseNetwork string restrictedNetwork string }{ { name: "bu1_development", - tfDir: "../../../4-projects/business_unit_1/development", + baseDir: "../../../4-projects/business_unit_1/%s", baseNetwork: fmt.Sprintf("vpc-d-shared-base%s", networkMode), restrictedNetwork: fmt.Sprintf("vpc-d-shared-restricted%s", networkMode), }, { name: "bu1_non-production", - tfDir: "../../../4-projects/business_unit_1/non-production", + baseDir: "../../../4-projects/business_unit_1/%s", baseNetwork: fmt.Sprintf("vpc-n-shared-base%s", networkMode), restrictedNetwork: fmt.Sprintf("vpc-n-shared-restricted%s", networkMode), }, { name: "bu1_production", - tfDir: "../../../4-projects/business_unit_1/production", + baseDir: "../../../4-projects/business_unit_1/%s", baseNetwork: fmt.Sprintf("vpc-p-shared-base%s", networkMode), restrictedNetwork: fmt.Sprintf("vpc-p-shared-restricted%s", networkMode), }, { name: "bu2_development", - tfDir: "../../../4-projects/business_unit_2/development", + baseDir: "../../../4-projects/business_unit_2/%s", baseNetwork: fmt.Sprintf("vpc-d-shared-base%s", networkMode), restrictedNetwork: fmt.Sprintf("vpc-d-shared-restricted%s", networkMode), }, { name: "bu2_non-production", - tfDir: "../../../4-projects/business_unit_2/non-production", + baseDir: "../../../4-projects/business_unit_2/%s", baseNetwork: fmt.Sprintf("vpc-n-shared-base%s", networkMode), restrictedNetwork: fmt.Sprintf("vpc-n-shared-restricted%s", networkMode), }, { name: "bu2_production", - tfDir: "../../../4-projects/business_unit_2/production", + baseDir: "../../../4-projects/business_unit_2/%s", baseNetwork: fmt.Sprintf("vpc-p-shared-base%s", networkMode), restrictedNetwork: fmt.Sprintf("vpc-p-shared-restricted%s", networkMode), }, } { t.Run(tt.name, func(t *testing.T) { - env := strings.Split(tt.name, "_") + env := testutils.GetLastSplitElement(tt.name, "_") netVars := map[string]interface{}{ "access_context_manager_policy_id": policyID, } @@ -189,31 +123,25 @@ func TestProjects(t *testing.T) { } networks := tft.NewTFBlueprintTest(t, - tft.WithTFDir(fmt.Sprintf(networkTFDir, env[1])), + tft.WithTFDir(fmt.Sprintf(networkTFDir, env)), tft.WithVars(netVars), ) perimeterName := networks.GetStringOutput("restricted_service_perimeter_name") + shared := tft.NewTFBlueprintTest(t, + tft.WithTFDir(fmt.Sprintf(tt.baseDir, "shared")), + ) + sharedCloudBuildSA := shared.GetStringOutput("cloudbuild_sa") + vars := map[string]interface{}{ - "app_infra_pipeline_cloudbuild_sa": sharedCloudBuildSA[env[0]], - "perimeter_name": perimeterName, - "access_context_manager_policy_id": policyID, + "backend_bucket": backend_bucket, } projects := tft.NewTFBlueprintTest(t, - tft.WithTFDir(tt.tfDir), + tft.WithTFDir(fmt.Sprintf(tt.baseDir, env)), tft.WithVars(vars), + tft.WithBackendConfig(backendConfig), ) - projects.DefineApply( - func(assert *assert.Assertions) { - // validate requirements - require.NotEmpty(t, sharedCloudBuildSA[env[0]], "app_infra_pipeline_cloudbuild_sa should not be empty") - require.NotEmpty(t, perimeterName, "perimeter_name should not be empty") - require.NotEmpty(t, policyID, "access_context_manager_policy_id should not be empty") - require.NotEmpty(t, terraformSA, "terraform_service_account should not be empty") - - projects.DefaultApply(assert) - }) projects.DefineVerify( func(assert *assert.Assertions) { @@ -245,7 +173,7 @@ func TestProjects(t *testing.T) { hostProjectID := sharedVPC.Get("name").String() hostProject := gcloud.Runf(t, "projects describe %s", hostProjectID) assert.Equal("restricted-shared-vpc-host", hostProject.Get("labels.application_name").String(), "host project should have application_name label equals to base-shared-vpc-host") - assert.Equal(env[1], hostProject.Get("labels.environment").String(), fmt.Sprintf("project should have environment label %s", env[1])) + assert.Equal(env, hostProject.Get("labels.environment").String(), fmt.Sprintf("project should have environment label %s", env)) hostNetwork := gcloud.Runf(t, "compute networks list --project %s", hostProjectID).Array()[0] assert.Equal(tt.restrictedNetwork, hostNetwork.Get("name").String(), "should have a shared vpc") @@ -257,7 +185,7 @@ func TestProjects(t *testing.T) { saName := projects.GetStringOutput("base_shared_vpc_project_sa") saPolicy := gcloud.Runf(t, "iam service-accounts get-iam-policy %s", saName) listSaMembers := utils.GetResultStrSlice(saPolicy.Get("bindings.0.members").Array()) - assert.Contains(listSaMembers, fmt.Sprintf("serviceAccount:%s", sharedCloudBuildSA[env[0]]), "service account should be member of the binding") + assert.Contains(listSaMembers, fmt.Sprintf("serviceAccount:%s", sharedCloudBuildSA), "service account should be member of the binding") assert.Equal("roles/iam.serviceAccountTokenCreator", saPolicy.Get("bindings.0.role").String(), "service account should have role serviceAccountTokenCreator") iamOpts := gcloud.WithCommonArgs([]string{"--flatten", "bindings", "--filter", "bindings.role:roles/editor", "--format", "json"}) @@ -271,7 +199,7 @@ func TestProjects(t *testing.T) { hostProjectID := sharedVPC.Get("name").String() hostProject := gcloud.Runf(t, "projects describe %s", hostProjectID) assert.Equal("base-shared-vpc-host", hostProject.Get("labels.application_name").String(), "host project should have application_name label equals to base-shared-vpc-host") - assert.Equal(env[1], hostProject.Get("labels.environment").String(), fmt.Sprintf("project should have environment label %s", env[1])) + assert.Equal(env, hostProject.Get("labels.environment").String(), fmt.Sprintf("project should have environment label %s", env)) hostNetwork := gcloud.Runf(t, "compute networks list --project %s", hostProjectID).Array()[0] assert.Equal(tt.baseNetwork, hostNetwork.Get("name").String(), "should have a shared vpc") diff --git a/test/integration/shared/shared_test.go b/test/integration/shared/shared_test.go index b1b0038de..5c49a1361 100644 --- a/test/integration/shared/shared_test.go +++ b/test/integration/shared/shared_test.go @@ -50,12 +50,18 @@ func TestShared(t *testing.T) { // Configure impersonation for test execution terraformSA := bootstrap.GetStringOutput("networks_step_terraform_service_account_email") utils.SetEnv(t, "GOOGLE_IMPERSONATE_SERVICE_ACCOUNT", terraformSA) + backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate") vars := map[string]interface{}{ "access_context_manager_policy_id": policyID, + "backend_bucket": backend_bucket, "terraform_service_account": terraformSA, } + backendConfig := map[string]interface{}{ + "bucket": backend_bucket, + } + var tfdDir string if getNetworkMode(t) { tfdDir = "../../../3-networks-hub-and-spoke/envs/shared" @@ -66,6 +72,7 @@ func TestShared(t *testing.T) { shared := tft.NewTFBlueprintTest(t, tft.WithTFDir(tfdDir), tft.WithVars(vars), + tft.WithBackendConfig(backendConfig), ) shared.DefineVerify( func(assert *assert.Assertions) { diff --git a/test/setup/outputs.tf b/test/setup/outputs.tf index 7986815de..1ae66ca22 100644 --- a/test/setup/outputs.tf +++ b/test/setup/outputs.tf @@ -73,7 +73,7 @@ output "project_prefix" { } output "domains_to_allow" { - value = [var.domain_to_allow] + value = tolist([var.domain_to_allow]) } output "target_name_server_addresses" { @@ -91,3 +91,7 @@ output "enable_hub_and_spoke" { output "enable_hub_and_spoke_transitivity" { value = var.example_foundations_mode == "HubAndSpoke" ? "true" : "false" } + +output "create_access_context_manager_access_policy" { + value = false +}