diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md index 9ab209815..21120f27c 100644 --- a/0-bootstrap/README.md +++ b/0-bootstrap/README.md @@ -307,6 +307,9 @@ Each step has instructions for this change. | bucket\_prefix | Name prefix to use for state bucket created. | `string` | `"bkt"` | no | | bucket\_tfstate\_kms\_force\_destroy | When deleting a bucket, this boolean option will delete the KMS keys used for the Terraform state bucket. | `bool` | `false` | no | | default\_region | Default region to create resources where applicable. | `string` | `"us-central1"` | no | +| default\_region\_2 | Secondary default region to create resources where applicable. | `string` | `"us-west1"` | no | +| default\_region\_gcs | Case-Sensitive default region to create gcs resources where applicable. | `string` | `"US"` | no | +| default\_region\_kms | Secondary default region to create kms resources where applicable. | `string` | `"us"` | no | | folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no | | groups | Contain the details of the Groups to be created. |
object({
create_required_groups = optional(bool, false)
create_optional_groups = optional(bool, false)
billing_project = optional(string, null)
required_groups = object({
group_org_admins = string
group_billing_admins = string
billing_data_users = string
audit_data_users = string
monitoring_workspace_users = string
})
optional_groups = optional(object({
gcp_security_reviewer = optional(string, "")
gcp_network_viewer = optional(string, "")
gcp_scc_admin = optional(string, "")
gcp_global_secrets_admin = optional(string, "")
gcp_kms_admin = optional(string, "")
}), {})
})
| n/a | yes | | initial\_group\_config | Define the group configuration when it is initialized. Valid values are: WITH\_INITIAL\_OWNER, EMPTY and INITIAL\_GROUP\_CONFIG\_UNSPECIFIED. | `string` | `"WITH_INITIAL_OWNER"` | no | diff --git a/0-bootstrap/modules/tfc-agent-gke/main.tf b/0-bootstrap/modules/tfc-agent-gke/main.tf index 39e641787..994af83d1 100644 --- a/0-bootstrap/modules/tfc-agent-gke/main.tf +++ b/0-bootstrap/modules/tfc-agent-gke/main.tf @@ -372,7 +372,7 @@ resource "google_compute_firewall" "allow_private_api_egress" { module "private_service_connect" { source = "terraform-google-modules/network/google//modules/private-service-connect" - version = "~> 9.0" + version = "~> 9.1" project_id = var.project_id dns_code = "dz-${local.vpc_name}" diff --git a/0-bootstrap/outputs.tf b/0-bootstrap/outputs.tf index 5f31b4ea0..81b1f77ab 100644 --- a/0-bootstrap/outputs.tf +++ b/0-bootstrap/outputs.tf @@ -56,6 +56,9 @@ output "common_config" { parent_folder = var.parent_folder, billing_account = var.billing_account, default_region = var.default_region, + default_region_2 = var.default_region_2, + default_region_gcs = var.default_region_gcs, + default_region_kms = var.default_region_kms, project_prefix = var.project_prefix, folder_prefix = var.folder_prefix parent_id = local.parent diff --git a/0-bootstrap/terraform.example.tfvars b/0-bootstrap/terraform.example.tfvars index 098b306fb..88e93f7d7 100644 --- a/0-bootstrap/terraform.example.tfvars +++ b/0-bootstrap/terraform.example.tfvars @@ -40,7 +40,10 @@ groups = { # } } -default_region = "us-central1" +default_region = "us-central1" +default_region_2 = "us-west1" +default_region_gcs = "US" +default_region_kms = "us" # Optional - for an organization with existing projects or for development/validation. # Uncomment this variable to place all the example foundation resources under diff --git a/0-bootstrap/variables.tf b/0-bootstrap/variables.tf index 58e70f730..ffd01bc83 100644 --- a/0-bootstrap/variables.tf +++ b/0-bootstrap/variables.tf @@ -30,6 +30,24 @@ variable "default_region" { default = "us-central1" } +variable "default_region_2" { + description = "Secondary default region to create resources where applicable." + type = string + default = "us-west1" +} + +variable "default_region_gcs" { + description = "Case-Sensitive default region to create gcs resources where applicable." + type = string + default = "US" +} + +variable "default_region_kms" { + description = "Secondary default region to create kms resources where applicable." + type = string + default = "us" +} + 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." type = string diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 8273fcb81..3934a9617 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -3,7 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| billing\_export\_dataset\_location | The location of the dataset for billing data export. | `string` | `"US"` | no | +| billing\_export\_dataset\_location | The location of the dataset for billing data export. | `string` | `null` | no | | cai\_monitoring\_kms\_force\_destroy | If set to true, delete KMS keyring and keys when destroying the module; otherwise, destroying the module will fail if KMS keys are present. | `bool` | `false` | no | | create\_access\_context\_manager\_access\_policy | Whether to create access context manager access policy. | `bool` | `true` | no | | create\_unique\_tag\_key | Creates unique organization-wide tag keys by adding a random suffix to each key. | `bool` | `false` | no | @@ -15,7 +15,7 @@ | essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no | | gcp\_groups | Groups to grant specific roles in the Organization.
platform\_viewer: Google Workspace or Cloud Identity group that have the ability to view resource information across the Google Cloud organization.
security\_reviewer: Google Workspace or Cloud Identity group that members are part of the security team responsible for reviewing cloud security
network\_viewer: Google Workspace or Cloud Identity group that members are part of the networking team and review network configurations.
scc\_admin: Google Workspace or Cloud Identity group that can administer Security Command Center.
audit\_viewer: Google Workspace or Cloud Identity group that members are part of an audit team and view audit logs in the logging project.
global\_secrets\_admin: Google Workspace or Cloud Identity group that members are responsible for putting secrets into Secrets Manage |
object({
audit_viewer = optional(string, null)
security_reviewer = optional(string, null)
network_viewer = optional(string, null)
scc_admin = optional(string, null)
global_secrets_admin = optional(string, null)
kms_admin = optional(string, null)
})
| `{}` | no | | log\_export\_storage\_force\_destroy | (Optional) If set to true, delete all contents when destroying the resource; otherwise, destroying the resource will fail if contents are present. | `bool` | `false` | no | -| log\_export\_storage\_location | The location of the storage bucket used to export logs. | `string` | `"US"` | no | +| log\_export\_storage\_location | The location of the storage bucket used to export logs. | `string` | `null` | no | | log\_export\_storage\_retention\_policy | Configuration of the bucket's data retention policy for how long objects in the bucket should be retained. |
object({
is_locked = bool
retention_period_days = number
})
| `null` | no | | log\_export\_storage\_versioning | (Optional) Toggles bucket versioning, ability to retain a non-current object version when the live object version gets replaced or deleted. | `bool` | `false` | no | | project\_budget | Budget configuration for projects.
budget\_amount: The amount to use as the budget.
alert\_spent\_percents: A list of percentages of the budget to alert on when threshold is exceeded.
alert\_pubsub\_topic: The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}`.
alert\_spend\_basis: The type of basis used to determine if spend has passed the threshold. Possible choices are `CURRENT_SPEND` or `FORECASTED_SPEND` (default). |
object({
dns_hub_budget_amount = optional(number, 1000)
dns_hub_alert_spent_percents = optional(list(number), [1.2])
dns_hub_alert_pubsub_topic = optional(string, null)
dns_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
base_net_hub_budget_amount = optional(number, 1000)
base_net_hub_alert_spent_percents = optional(list(number), [1.2])
base_net_hub_alert_pubsub_topic = optional(string, null)
base_net_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
base_network_budget_amount = optional(number, 1000)
base_network_alert_spent_percents = optional(list(number), [1.2])
base_network_alert_pubsub_topic = optional(string, null)
base_network_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
restricted_net_hub_budget_amount = optional(number, 1000)
restricted_net_hub_alert_spent_percents = optional(list(number), [1.2])
restricted_net_hub_alert_pubsub_topic = optional(string, null)
restricted_net_hub_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
restricted_network_budget_amount = optional(number, 1000)
restricted_network_alert_spent_percents = optional(list(number), [1.2])
restricted_network_alert_pubsub_topic = optional(string, null)
restricted_network_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
interconnect_budget_amount = optional(number, 1000)
interconnect_alert_spent_percents = optional(list(number), [1.2])
interconnect_alert_pubsub_topic = optional(string, null)
interconnect_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_secrets_budget_amount = optional(number, 1000)
org_secrets_alert_spent_percents = optional(list(number), [1.2])
org_secrets_alert_pubsub_topic = optional(string, null)
org_secrets_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_billing_logs_budget_amount = optional(number, 1000)
org_billing_logs_alert_spent_percents = optional(list(number), [1.2])
org_billing_logs_alert_pubsub_topic = optional(string, null)
org_billing_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_audit_logs_budget_amount = optional(number, 1000)
org_audit_logs_alert_spent_percents = optional(list(number), [1.2])
org_audit_logs_alert_pubsub_topic = optional(string, null)
org_audit_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_kms_budget_amount = optional(number, 1000)
org_kms_alert_spent_percents = optional(list(number), [1.2])
org_kms_alert_pubsub_topic = optional(string, null)
org_kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
scc_notifications_budget_amount = optional(number, 1000)
scc_notifications_alert_spent_percents = optional(list(number), [1.2])
scc_notifications_alert_pubsub_topic = optional(string, null)
scc_notifications_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
})
| `{}` | no | diff --git a/1-org/envs/shared/log_sinks.tf b/1-org/envs/shared/log_sinks.tf index c32783fc5..45f0f2178 100644 --- a/1-org/envs/shared/log_sinks.tf +++ b/1-org/envs/shared/log_sinks.tf @@ -53,7 +53,7 @@ module "logs_export" { logging_sink_filter = local.logs_filter logging_sink_name = "sk-c-logging-bkt" storage_bucket_name = "bkt-${module.org_audit_logs.project_id}-org-logs-${random_string.suffix.result}" - location = var.log_export_storage_location + location = coalesce(var.log_export_storage_location, local.default_region) retention_policy_enabled = var.log_export_storage_retention_policy != null retention_policy_is_locked = var.log_export_storage_retention_policy == null ? null : var.log_export_storage_retention_policy.is_locked retention_policy_period_days = var.log_export_storage_retention_policy == null ? null : var.log_export_storage_retention_policy.retention_period_days @@ -93,5 +93,5 @@ resource "google_bigquery_dataset" "billing_dataset" { dataset_id = "billing_data" project = module.org_billing_logs.project_id friendly_name = "GCP Billing Data" - location = var.billing_export_dataset_location + location = coalesce(var.billing_export_dataset_location, local.default_region) } diff --git a/1-org/envs/shared/terraform.example.tfvars b/1-org/envs/shared/terraform.example.tfvars index a43d1938e..9ff38bde8 100644 --- a/1-org/envs/shared/terraform.example.tfvars +++ b/1-org/envs/shared/terraform.example.tfvars @@ -23,6 +23,10 @@ scc_notification_name = "scc-notify" remote_state_bucket = "REMOTE_STATE_BUCKET" +log_export_storage_location = "US" + +billing_export_dataset_location = "US" + //scc_notification_filter = "state=\\\"ACTIVE\\\"" //enable_hub_and_spoke = true diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index d7f860098..e449411d4 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -57,13 +57,13 @@ variable "data_access_logs_enabled" { variable "log_export_storage_location" { description = "The location of the storage bucket used to export logs." type = string - default = "US" + default = null } variable "billing_export_dataset_location" { description = "The location of the dataset for billing data export." type = string - default = "US" + default = null } variable "log_export_storage_force_destroy" { diff --git a/3-networks-dual-svpc/envs/development/main.tf b/3-networks-dual-svpc/envs/development/main.tf index bf158dc36..b7d394786 100644 --- a/3-networks-dual-svpc/envs/development/main.tf +++ b/3-networks-dual-svpc/envs/development/main.tf @@ -17,8 +17,6 @@ locals { env = "development" environment_code = substr(local.env, 0, 1) - default_region1 = "us-west1" - default_region2 = "us-central1" /* * Base network ranges */ diff --git a/3-networks-dual-svpc/envs/development/remote.tf b/3-networks-dual-svpc/envs/development/remote.tf new file mode 100644 index 000000000..e2e5b151d --- /dev/null +++ b/3-networks-dual-svpc/envs/development/remote.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/3-networks-dual-svpc/envs/development/remote.tf.cloud.example b/3-networks-dual-svpc/envs/development/remote.tf.cloud.example new file mode 100644 index 000000000..006f690eb --- /dev/null +++ b/3-networks-dual-svpc/envs/development/remote.tf.cloud.example @@ -0,0 +1,25 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/3-networks-dual-svpc/envs/nonproduction/main.tf b/3-networks-dual-svpc/envs/nonproduction/main.tf index 213b13246..51a32c8c3 100644 --- a/3-networks-dual-svpc/envs/nonproduction/main.tf +++ b/3-networks-dual-svpc/envs/nonproduction/main.tf @@ -17,8 +17,6 @@ locals { env = "nonproduction" environment_code = substr(local.env, 0, 1) - default_region1 = "us-west1" - default_region2 = "us-central1" /* * Base network ranges */ diff --git a/3-networks-dual-svpc/envs/nonproduction/remote.tf b/3-networks-dual-svpc/envs/nonproduction/remote.tf new file mode 100644 index 000000000..e2e5b151d --- /dev/null +++ b/3-networks-dual-svpc/envs/nonproduction/remote.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/3-networks-dual-svpc/envs/nonproduction/remote.tf.cloud.example b/3-networks-dual-svpc/envs/nonproduction/remote.tf.cloud.example new file mode 100644 index 000000000..006f690eb --- /dev/null +++ b/3-networks-dual-svpc/envs/nonproduction/remote.tf.cloud.example @@ -0,0 +1,25 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/3-networks-dual-svpc/envs/production/main.tf b/3-networks-dual-svpc/envs/production/main.tf index fa6a12521..35a80fc81 100644 --- a/3-networks-dual-svpc/envs/production/main.tf +++ b/3-networks-dual-svpc/envs/production/main.tf @@ -17,8 +17,6 @@ locals { env = "production" environment_code = substr(local.env, 0, 1) - default_region1 = "us-west1" - default_region2 = "us-central1" /* * Base network ranges */ diff --git a/3-networks-dual-svpc/envs/production/remote.tf b/3-networks-dual-svpc/envs/production/remote.tf new file mode 100644 index 000000000..e2e5b151d --- /dev/null +++ b/3-networks-dual-svpc/envs/production/remote.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/3-networks-dual-svpc/envs/production/remote.tf.cloud.example b/3-networks-dual-svpc/envs/production/remote.tf.cloud.example new file mode 100644 index 000000000..006f690eb --- /dev/null +++ b/3-networks-dual-svpc/envs/production/remote.tf.cloud.example @@ -0,0 +1,25 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/3-networks-dual-svpc/envs/shared/remote.tf b/3-networks-dual-svpc/envs/shared/remote.tf index 54a4418ca..8bb1ddc51 100644 --- a/3-networks-dual-svpc/envs/shared/remote.tf +++ b/3-networks-dual-svpc/envs/shared/remote.tf @@ -18,8 +18,8 @@ locals { env = "common" environment_code = "c" dns_bgp_asn_number = var.enable_partner_interconnect ? "16550" : var.bgp_asn_dns - default_region1 = "us-west1" - default_region2 = "us-central1" + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 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 diff --git a/3-networks-dual-svpc/envs/shared/remote.tf.cloud.example b/3-networks-dual-svpc/envs/shared/remote.tf.cloud.example index 6f87753ca..f12825173 100644 --- a/3-networks-dual-svpc/envs/shared/remote.tf.cloud.example +++ b/3-networks-dual-svpc/envs/shared/remote.tf.cloud.example @@ -18,8 +18,8 @@ locals { env = "common" environment_code = "c" dns_bgp_asn_number = var.enable_partner_interconnect ? "16550" : var.bgp_asn_dns - default_region1 = "us-west1" - default_region2 = "us-central1" + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 folder_prefix = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.folder_prefix dns_hub_project_id = data.tfe_outputs.org.nonsensitive_values.dns_hub_project_id interconnect_project_id = data.tfe_outputs.org.nonsensitive_values.interconnect_project_id diff --git a/3-networks-dual-svpc/modules/base_shared_vpc/private_service_connect.tf b/3-networks-dual-svpc/modules/base_shared_vpc/private_service_connect.tf index 6840b7587..617c93930 100644 --- a/3-networks-dual-svpc/modules/base_shared_vpc/private_service_connect.tf +++ b/3-networks-dual-svpc/modules/base_shared_vpc/private_service_connect.tf @@ -17,11 +17,12 @@ module "private_service_connect" { source = "terraform-google-modules/network/google//modules/private-service-connect" - version = "~> 9.0" + version = "~> 9.1" project_id = var.project_id dns_code = "dz-${var.environment_code}-shared-base" network_self_link = module.main.network_self_link private_service_connect_ip = var.private_service_connect_ip forwarding_rule_target = "all-apis" + service_directory_region = var.default_region1 } diff --git a/3-networks-dual-svpc/modules/restricted_shared_vpc/private_service_connect.tf b/3-networks-dual-svpc/modules/restricted_shared_vpc/private_service_connect.tf index f5b6beeba..452625170 100644 --- a/3-networks-dual-svpc/modules/restricted_shared_vpc/private_service_connect.tf +++ b/3-networks-dual-svpc/modules/restricted_shared_vpc/private_service_connect.tf @@ -17,11 +17,12 @@ module "private_service_connect" { source = "terraform-google-modules/network/google//modules/private-service-connect" - version = "~> 9.0" + version = "~> 9.1" project_id = var.project_id dns_code = "dz-${var.environment_code}-shared-restricted" network_self_link = module.main.network_self_link private_service_connect_ip = var.private_service_connect_ip forwarding_rule_target = "vpc-sc" + service_directory_region = var.default_region1 } diff --git a/3-networks-hub-and-spoke/envs/development/main.tf b/3-networks-hub-and-spoke/envs/development/main.tf index f7dbd75bc..db7388fc8 100644 --- a/3-networks-hub-and-spoke/envs/development/main.tf +++ b/3-networks-hub-and-spoke/envs/development/main.tf @@ -17,8 +17,6 @@ locals { env = "development" environment_code = substr(local.env, 0, 1) - default_region1 = "us-west1" - default_region2 = "us-central1" /* * Base network ranges */ diff --git a/3-networks-hub-and-spoke/envs/development/remote.tf b/3-networks-hub-and-spoke/envs/development/remote.tf new file mode 100644 index 000000000..e2e5b151d --- /dev/null +++ b/3-networks-hub-and-spoke/envs/development/remote.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/3-networks-hub-and-spoke/envs/development/remote.tf.cloud.example b/3-networks-hub-and-spoke/envs/development/remote.tf.cloud.example new file mode 100644 index 000000000..006f690eb --- /dev/null +++ b/3-networks-hub-and-spoke/envs/development/remote.tf.cloud.example @@ -0,0 +1,25 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/3-networks-hub-and-spoke/envs/nonproduction/main.tf b/3-networks-hub-and-spoke/envs/nonproduction/main.tf index 22c4c1df5..f2660a33f 100644 --- a/3-networks-hub-and-spoke/envs/nonproduction/main.tf +++ b/3-networks-hub-and-spoke/envs/nonproduction/main.tf @@ -17,8 +17,6 @@ locals { env = "nonproduction" environment_code = substr(local.env, 0, 1) - default_region1 = "us-west1" - default_region2 = "us-central1" /* * Base network ranges */ diff --git a/3-networks-hub-and-spoke/envs/nonproduction/remote.tf b/3-networks-hub-and-spoke/envs/nonproduction/remote.tf new file mode 100644 index 000000000..e2e5b151d --- /dev/null +++ b/3-networks-hub-and-spoke/envs/nonproduction/remote.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/3-networks-hub-and-spoke/envs/nonproduction/remote.tf.cloud.example b/3-networks-hub-and-spoke/envs/nonproduction/remote.tf.cloud.example new file mode 100644 index 000000000..006f690eb --- /dev/null +++ b/3-networks-hub-and-spoke/envs/nonproduction/remote.tf.cloud.example @@ -0,0 +1,25 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/3-networks-hub-and-spoke/envs/production/main.tf b/3-networks-hub-and-spoke/envs/production/main.tf index 1fc54baa6..879600aea 100644 --- a/3-networks-hub-and-spoke/envs/production/main.tf +++ b/3-networks-hub-and-spoke/envs/production/main.tf @@ -17,8 +17,6 @@ locals { env = "production" environment_code = substr(local.env, 0, 1) - default_region1 = "us-west1" - default_region2 = "us-central1" /* * Base network ranges */ diff --git a/3-networks-hub-and-spoke/envs/production/remote.tf b/3-networks-hub-and-spoke/envs/production/remote.tf new file mode 100644 index 000000000..e2e5b151d --- /dev/null +++ b/3-networks-hub-and-spoke/envs/production/remote.tf @@ -0,0 +1,29 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/3-networks-hub-and-spoke/envs/production/remote.tf.cloud.example b/3-networks-hub-and-spoke/envs/production/remote.tf.cloud.example new file mode 100644 index 000000000..006f690eb --- /dev/null +++ b/3-networks-hub-and-spoke/envs/production/remote.tf.cloud.example @@ -0,0 +1,25 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/3-networks-hub-and-spoke/envs/shared/main.tf b/3-networks-hub-and-spoke/envs/shared/main.tf index a276b0a8e..891fa4eba 100644 --- a/3-networks-hub-and-spoke/envs/shared/main.tf +++ b/3-networks-hub-and-spoke/envs/shared/main.tf @@ -19,8 +19,6 @@ locals { environment_code = "c" bgp_asn_number = var.enable_partner_interconnect ? "16550" : "64514" dns_bgp_asn_number = var.enable_partner_interconnect ? "16550" : var.bgp_asn_dns - default_region1 = "us-west1" - default_region2 = "us-central1" dedicated_interconnect_egress_policy = var.enable_dedicated_interconnect ? [ { diff --git a/3-networks-hub-and-spoke/envs/shared/remote.tf b/3-networks-hub-and-spoke/envs/shared/remote.tf index 0ce304ba7..6660a6627 100644 --- a/3-networks-hub-and-spoke/envs/shared/remote.tf +++ b/3-networks-hub-and-spoke/envs/shared/remote.tf @@ -22,6 +22,8 @@ locals { 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 + default_region1 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 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 diff --git a/3-networks-hub-and-spoke/envs/shared/remote.tf.cloud.example b/3-networks-hub-and-spoke/envs/shared/remote.tf.cloud.example index 7a23200c1..127d907ee 100644 --- a/3-networks-hub-and-spoke/envs/shared/remote.tf.cloud.example +++ b/3-networks-hub-and-spoke/envs/shared/remote.tf.cloud.example @@ -21,7 +21,9 @@ locals { parent_folder = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.parent_folder org_id = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.org_id billing_account = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.billing_account - default_region = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.default_region + default_region = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region1 = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 project_prefix = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.project_prefix folder_prefix = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.folder_prefix parent_id = data.tfe_outputs.bootstrap.nonsensitive_values.common_config.parent_id diff --git a/3-networks-hub-and-spoke/modules/base_shared_vpc/private_service_connect.tf b/3-networks-hub-and-spoke/modules/base_shared_vpc/private_service_connect.tf index 6840b7587..864e6ee37 100644 --- a/3-networks-hub-and-spoke/modules/base_shared_vpc/private_service_connect.tf +++ b/3-networks-hub-and-spoke/modules/base_shared_vpc/private_service_connect.tf @@ -17,7 +17,7 @@ module "private_service_connect" { source = "terraform-google-modules/network/google//modules/private-service-connect" - version = "~> 9.0" + version = "~> 9.1" project_id = var.project_id dns_code = "dz-${var.environment_code}-shared-base" diff --git a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/private_service_connect.tf b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/private_service_connect.tf index f5b6beeba..33f407fa6 100644 --- a/3-networks-hub-and-spoke/modules/restricted_shared_vpc/private_service_connect.tf +++ b/3-networks-hub-and-spoke/modules/restricted_shared_vpc/private_service_connect.tf @@ -17,7 +17,7 @@ module "private_service_connect" { source = "terraform-google-modules/network/google//modules/private-service-connect" - version = "~> 9.0" + version = "~> 9.1" project_id = var.project_id dns_code = "dz-${var.environment_code}-shared-restricted" diff --git a/4-projects/business_unit_1/development/README.md b/4-projects/business_unit_1/development/README.md index b6841087a..05729e0b1 100644 --- a/4-projects/business_unit_1/development/README.md +++ b/4-projects/business_unit_1/development/README.md @@ -3,9 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| instance\_region | Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project). | `string` | `"us-central1"` | no | -| 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 | +| gcs\_custom\_placement\_config | Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null. |
object({
data_locations = list(string)
})
| `null` | no | +| instance\_region | Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project). | `string` | `null` | no | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `null` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `null` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization. | `string` | `""` | no | @@ -19,6 +20,7 @@ | base\_shared\_vpc\_project\_sa | Project sample base project SA. | | base\_subnets\_self\_links | The self-links of subnets from base environment. | | bucket | The created storage bucket. | +| default\_region | The default region for the project. | | env\_kms\_project | Project sample for KMS usage project ID. | | floating\_project | Project sample floating project. | | iap\_firewall\_tags | The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project. | diff --git a/4-projects/business_unit_1/development/main.tf b/4-projects/business_unit_1/development/main.tf index 0359d2e73..b2efde30d 100644 --- a/4-projects/business_unit_1/development/main.tf +++ b/4-projects/business_unit_1/development/main.tf @@ -17,15 +17,21 @@ module "env" { source = "../../modules/base_env" - env = "development" - business_code = "bu1" - business_unit = "business_unit_1" - remote_state_bucket = var.remote_state_bucket - location_kms = var.location_kms - location_gcs = var.location_gcs + env = "development" + business_code = "bu1" + business_unit = "business_unit_1" + remote_state_bucket = var.remote_state_bucket + location_kms = coalesce(var.location_kms, local.default_region_kms) + location_gcs = coalesce(var.location_gcs, local.default_region_gcs) + gcs_custom_placement_config = { + data_locations = [ + upper(local.default_region), + upper(local.default_region_2), + ] + } tfc_org_name = var.tfc_org_name peering_module_depends_on = var.peering_module_depends_on peering_iap_fw_rules_enabled = true - subnet_region = var.instance_region + subnet_region = coalesce(var.instance_region, local.default_region) subnet_ip_range = "10.3.64.0/21" } diff --git a/4-projects/business_unit_1/development/outputs.tf b/4-projects/business_unit_1/development/outputs.tf index 6f07af601..feef5c507 100644 --- a/4-projects/business_unit_1/development/outputs.tf +++ b/4-projects/business_unit_1/development/outputs.tf @@ -108,3 +108,8 @@ output "iap_firewall_tags" { description = "The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project." value = module.env.iap_firewall_tags } + +output "default_region" { + description = "The default region for the project." + value = local.default_region +} diff --git a/4-projects/business_unit_1/development/remote.tf b/4-projects/business_unit_1/development/remote.tf new file mode 100644 index 000000000..4a39ce1c3 --- /dev/null +++ b/4-projects/business_unit_1/development/remote.tf @@ -0,0 +1,31 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region_2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 + default_region_gcs = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_gcs + default_region_kms = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_kms +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/4-projects/business_unit_1/development/remote.tf.cloud.example b/4-projects/business_unit_1/development/remote.tf.cloud.example new file mode 100644 index 000000000..bf965421e --- /dev/null +++ b/4-projects/business_unit_1/development/remote.tf.cloud.example @@ -0,0 +1,27 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region_2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 + default_region_gcs = data.tfe_outputs.bootstrap.outputs.common_config.default_region_gcs + default_region_kms = data.tfe_outputs.bootstrap.outputs.common_config.default_region_kms +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/4-projects/business_unit_1/development/variables.tf b/4-projects/business_unit_1/development/variables.tf index b337bae90..0b055e98f 100644 --- a/4-projects/business_unit_1/development/variables.tf +++ b/4-projects/business_unit_1/development/variables.tf @@ -22,13 +22,21 @@ variable "remote_state_bucket" { variable "location_kms" { description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string - default = "us" + default = null } variable "location_gcs" { description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string - default = "US" + default = null +} + +variable "gcs_custom_placement_config" { + description = "Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null." + type = object({ + data_locations = list(string) + }) + default = null } variable "peering_module_depends_on" { @@ -46,5 +54,5 @@ variable "tfc_org_name" { variable "instance_region" { description = "Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project)." type = string - default = "us-central1" + default = null } diff --git a/4-projects/business_unit_1/nonproduction/README.md b/4-projects/business_unit_1/nonproduction/README.md index b6841087a..05729e0b1 100644 --- a/4-projects/business_unit_1/nonproduction/README.md +++ b/4-projects/business_unit_1/nonproduction/README.md @@ -3,9 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| instance\_region | Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project). | `string` | `"us-central1"` | no | -| 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 | +| gcs\_custom\_placement\_config | Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null. |
object({
data_locations = list(string)
})
| `null` | no | +| instance\_region | Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project). | `string` | `null` | no | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `null` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `null` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization. | `string` | `""` | no | @@ -19,6 +20,7 @@ | base\_shared\_vpc\_project\_sa | Project sample base project SA. | | base\_subnets\_self\_links | The self-links of subnets from base environment. | | bucket | The created storage bucket. | +| default\_region | The default region for the project. | | env\_kms\_project | Project sample for KMS usage project ID. | | floating\_project | Project sample floating project. | | iap\_firewall\_tags | The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project. | diff --git a/4-projects/business_unit_1/nonproduction/main.tf b/4-projects/business_unit_1/nonproduction/main.tf index b48e1594c..ef954c892 100644 --- a/4-projects/business_unit_1/nonproduction/main.tf +++ b/4-projects/business_unit_1/nonproduction/main.tf @@ -17,15 +17,21 @@ module "env" { source = "../../modules/base_env" - env = "nonproduction" - business_code = "bu1" - business_unit = "business_unit_1" - remote_state_bucket = var.remote_state_bucket - location_kms = var.location_kms - location_gcs = var.location_gcs + env = "nonproduction" + business_code = "bu1" + business_unit = "business_unit_1" + remote_state_bucket = var.remote_state_bucket + location_kms = coalesce(var.location_kms, local.default_region_kms) + location_gcs = coalesce(var.location_gcs, local.default_region_gcs) + gcs_custom_placement_config = { + data_locations = [ + upper(local.default_region), + upper(local.default_region_2), + ] + } tfc_org_name = var.tfc_org_name peering_module_depends_on = var.peering_module_depends_on peering_iap_fw_rules_enabled = true - subnet_region = var.instance_region + subnet_region = coalesce(var.instance_region, local.default_region) subnet_ip_range = "10.3.128.0/21" } diff --git a/4-projects/business_unit_1/nonproduction/outputs.tf b/4-projects/business_unit_1/nonproduction/outputs.tf index 6f07af601..feef5c507 100644 --- a/4-projects/business_unit_1/nonproduction/outputs.tf +++ b/4-projects/business_unit_1/nonproduction/outputs.tf @@ -108,3 +108,8 @@ output "iap_firewall_tags" { description = "The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project." value = module.env.iap_firewall_tags } + +output "default_region" { + description = "The default region for the project." + value = local.default_region +} diff --git a/4-projects/business_unit_1/nonproduction/remote.tf b/4-projects/business_unit_1/nonproduction/remote.tf new file mode 100644 index 000000000..4a39ce1c3 --- /dev/null +++ b/4-projects/business_unit_1/nonproduction/remote.tf @@ -0,0 +1,31 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region_2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 + default_region_gcs = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_gcs + default_region_kms = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_kms +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/4-projects/business_unit_1/nonproduction/remote.tf.cloud.example b/4-projects/business_unit_1/nonproduction/remote.tf.cloud.example new file mode 100644 index 000000000..bf965421e --- /dev/null +++ b/4-projects/business_unit_1/nonproduction/remote.tf.cloud.example @@ -0,0 +1,27 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region_2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 + default_region_gcs = data.tfe_outputs.bootstrap.outputs.common_config.default_region_gcs + default_region_kms = data.tfe_outputs.bootstrap.outputs.common_config.default_region_kms +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/4-projects/business_unit_1/nonproduction/variables.tf b/4-projects/business_unit_1/nonproduction/variables.tf index b337bae90..0b055e98f 100644 --- a/4-projects/business_unit_1/nonproduction/variables.tf +++ b/4-projects/business_unit_1/nonproduction/variables.tf @@ -22,13 +22,21 @@ variable "remote_state_bucket" { variable "location_kms" { description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string - default = "us" + default = null } variable "location_gcs" { description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string - default = "US" + default = null +} + +variable "gcs_custom_placement_config" { + description = "Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null." + type = object({ + data_locations = list(string) + }) + default = null } variable "peering_module_depends_on" { @@ -46,5 +54,5 @@ variable "tfc_org_name" { variable "instance_region" { description = "Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project)." type = string - default = "us-central1" + default = null } diff --git a/4-projects/business_unit_1/production/README.md b/4-projects/business_unit_1/production/README.md index b6841087a..05729e0b1 100644 --- a/4-projects/business_unit_1/production/README.md +++ b/4-projects/business_unit_1/production/README.md @@ -3,9 +3,10 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| instance\_region | Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project). | `string` | `"us-central1"` | no | -| 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 | +| gcs\_custom\_placement\_config | Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null. |
object({
data_locations = list(string)
})
| `null` | no | +| instance\_region | Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project). | `string` | `null` | no | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | `null` | no | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | `null` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | | remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes | | tfc\_org\_name | Name of the TFC organization. | `string` | `""` | no | @@ -19,6 +20,7 @@ | base\_shared\_vpc\_project\_sa | Project sample base project SA. | | base\_subnets\_self\_links | The self-links of subnets from base environment. | | bucket | The created storage bucket. | +| default\_region | The default region for the project. | | env\_kms\_project | Project sample for KMS usage project ID. | | floating\_project | Project sample floating project. | | iap\_firewall\_tags | The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project. | diff --git a/4-projects/business_unit_1/production/main.tf b/4-projects/business_unit_1/production/main.tf index 5a5d475ca..cdc136052 100644 --- a/4-projects/business_unit_1/production/main.tf +++ b/4-projects/business_unit_1/production/main.tf @@ -17,15 +17,21 @@ module "env" { source = "../../modules/base_env" - env = "production" - business_code = "bu1" - business_unit = "business_unit_1" - remote_state_bucket = var.remote_state_bucket - location_kms = var.location_kms - location_gcs = var.location_gcs + env = "production" + business_code = "bu1" + business_unit = "business_unit_1" + remote_state_bucket = var.remote_state_bucket + location_kms = coalesce(var.location_kms, local.default_region_kms) + location_gcs = coalesce(var.location_gcs, local.default_region_gcs) + gcs_custom_placement_config = { + data_locations = [ + upper(local.default_region), + upper(local.default_region_2), + ] + } tfc_org_name = var.tfc_org_name peering_module_depends_on = var.peering_module_depends_on peering_iap_fw_rules_enabled = true - subnet_region = var.instance_region + subnet_region = coalesce(var.instance_region, local.default_region) subnet_ip_range = "10.3.192.0/21" } diff --git a/4-projects/business_unit_1/production/outputs.tf b/4-projects/business_unit_1/production/outputs.tf index 6f07af601..e8a821c7b 100644 --- a/4-projects/business_unit_1/production/outputs.tf +++ b/4-projects/business_unit_1/production/outputs.tf @@ -108,3 +108,9 @@ output "iap_firewall_tags" { description = "The security tags created for IAP (SSH and RDP) firewall rules and to be used on the VM created on step 5-app-infra on the peering network project." value = module.env.iap_firewall_tags } + +output "default_region" { + description = "The default region for the project." + value = local.default_region +} + diff --git a/4-projects/business_unit_1/production/remote.tf b/4-projects/business_unit_1/production/remote.tf new file mode 100644 index 000000000..4a39ce1c3 --- /dev/null +++ b/4-projects/business_unit_1/production/remote.tf @@ -0,0 +1,31 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region + default_region_2 = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_2 + default_region_gcs = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_gcs + default_region_kms = data.terraform_remote_state.bootstrap.outputs.common_config.default_region_kms +} + +data "terraform_remote_state" "bootstrap" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/bootstrap/state" + } +} diff --git a/4-projects/business_unit_1/production/remote.tf.cloud.example b/4-projects/business_unit_1/production/remote.tf.cloud.example new file mode 100644 index 000000000..bf965421e --- /dev/null +++ b/4-projects/business_unit_1/production/remote.tf.cloud.example @@ -0,0 +1,27 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.tfe_outputs.bootstrap.outputs.common_config.default_region + default_region_2 = data.tfe_outputs.bootstrap.outputs.common_config.default_region_2 + default_region_gcs = data.tfe_outputs.bootstrap.outputs.common_config.default_region_gcs + default_region_kms = data.tfe_outputs.bootstrap.outputs.common_config.default_region_kms +} + +data "tfe_outputs" "bootstrap" { + organization = var.tfc_org_name + workspace = "0-shared" +} diff --git a/4-projects/business_unit_1/production/variables.tf b/4-projects/business_unit_1/production/variables.tf index b337bae90..0b055e98f 100644 --- a/4-projects/business_unit_1/production/variables.tf +++ b/4-projects/business_unit_1/production/variables.tf @@ -22,13 +22,21 @@ variable "remote_state_bucket" { variable "location_kms" { description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string - default = "us" + default = null } variable "location_gcs" { description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string - default = "US" + default = null +} + +variable "gcs_custom_placement_config" { + description = "Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null." + type = object({ + data_locations = list(string) + }) + default = null } variable "peering_module_depends_on" { @@ -46,5 +54,5 @@ variable "tfc_org_name" { variable "instance_region" { description = "Region which the peered subnet will be created (Should be same region as the VM that will be created on step 5-app-infra on the peering project)." type = string - default = "us-central1" + default = null } diff --git a/4-projects/development.auto.example.tfvars b/4-projects/development.auto.example.tfvars index f63111f83..03b55b19a 100644 --- a/4-projects/development.auto.example.tfvars +++ b/4-projects/development.auto.example.tfvars @@ -14,5 +14,5 @@ * limitations under the License. */ -location_kms = "us" -location_gcs = "US" +# 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 c0d404922..8e3acc392 100644 --- a/4-projects/modules/base_env/README.md +++ b/4-projects/modules/base_env/README.md @@ -9,12 +9,13 @@ | 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` | `"bkt"` | no | +| gcs\_custom\_placement\_config | Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null. |
object({
data_locations = list(string)
})
| n/a | yes | | 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 | | keyring\_name | Name to be used for KMS Keyring | `string` | `"sample-keyring"` | no | | kms\_prj\_suffix | Name suffix to use for KMS project created. | `string` | `"kms"` | no | -| 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 | +| location\_gcs | Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring) | `string` | n/a | yes | +| location\_kms | Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket) | `string` | n/a | yes | | optional\_fw\_rules\_enabled | Toggle creation of optional firewall rules: Internal & Global load balancing health check and load balancing IP ranges. | `bool` | `false` | no | | peering\_iap\_fw\_rules\_enabled | Toggle creation of optional IAP firewall rules: SSH, RDP. | `bool` | `false` | no | | peering\_module\_depends\_on | List of modules or resources peering module depends on. | `list(any)` | `[]` | no | diff --git a/4-projects/modules/base_env/example_storage_cmek.tf b/4-projects/modules/base_env/example_storage_cmek.tf index 4acaf40a5..f72e15d42 100644 --- a/4-projects/modules/base_env/example_storage_cmek.tf +++ b/4-projects/modules/base_env/example_storage_cmek.tf @@ -67,10 +67,11 @@ module "gcs_buckets" { source = "terraform-google-modules/cloud-storage/google//modules/simple_bucket" version = "~> 6.0" - project_id = module.base_shared_vpc_project.project_id - location = var.location_gcs - name = "${var.gcs_bucket_prefix}-${module.base_shared_vpc_project.project_id}-${lower(var.location_gcs)}-cmek-encrypted-${random_string.bucket_name.result}" - bucket_policy_only = true + project_id = module.base_shared_vpc_project.project_id + location = var.location_gcs + name = "${var.gcs_bucket_prefix}-${module.base_shared_vpc_project.project_id}-${lower(var.location_gcs)}-cmek-encrypted-${random_string.bucket_name.result}" + bucket_policy_only = true + custom_placement_config = var.gcs_custom_placement_config encryption = { default_kms_key_name = module.kms.keys[var.key_name] diff --git a/4-projects/modules/base_env/variables.tf b/4-projects/modules/base_env/variables.tf index 25412be4e..0c81a4110 100644 --- a/4-projects/modules/base_env/variables.tf +++ b/4-projects/modules/base_env/variables.tf @@ -97,13 +97,18 @@ variable "kms_prj_suffix" { variable "location_kms" { description = "Case-Sensitive Location for KMS Keyring (Should be same region as the GCS Bucket)" type = string - default = "us" } variable "location_gcs" { description = "Case-Sensitive Location for GCS Bucket (Should be same region as the KMS Keyring)" type = string - default = "US" +} + +variable "gcs_custom_placement_config" { + description = "Configuration of the bucket's custom location in a dual-region bucket setup. If the bucket is designated a single or multi-region, the variable are null." + type = object({ + data_locations = list(string) + }) } variable "keyring_name" { diff --git a/4-projects/nonproduction.auto.example.tfvars b/4-projects/nonproduction.auto.example.tfvars index f63111f83..03b55b19a 100644 --- a/4-projects/nonproduction.auto.example.tfvars +++ b/4-projects/nonproduction.auto.example.tfvars @@ -14,5 +14,5 @@ * limitations under the License. */ -location_kms = "us" -location_gcs = "US" +# location_kms = "us" +# location_gcs = "US" diff --git a/4-projects/production.auto.example.tfvars b/4-projects/production.auto.example.tfvars index f63111f83..03b55b19a 100644 --- a/4-projects/production.auto.example.tfvars +++ b/4-projects/production.auto.example.tfvars @@ -14,5 +14,5 @@ * limitations under the License. */ -location_kms = "us" -location_gcs = "US" +# location_kms = "us" +# location_gcs = "US" diff --git a/5-app-infra/business_unit_1/development/README.md b/5-app-infra/business_unit_1/development/README.md index 56d20b016..6809c65cf 100644 --- a/5-app-infra/business_unit_1/development/README.md +++ b/5-app-infra/business_unit_1/development/README.md @@ -3,7 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | n/a | yes | +| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | `null` | no | | remote\_state\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | ## Outputs diff --git a/5-app-infra/business_unit_1/development/main.tf b/5-app-infra/business_unit_1/development/main.tf index d473670be..4fbe40bdd 100644 --- a/5-app-infra/business_unit_1/development/main.tf +++ b/5-app-infra/business_unit_1/development/main.tf @@ -25,7 +25,7 @@ module "base_shared_gce_instance" { environment = local.environment business_unit = local.business_unit project_suffix = "sample-base" - region = var.instance_region + region = coalesce(var.instance_region, local.default_region) remote_state_bucket = var.remote_state_bucket } @@ -35,6 +35,6 @@ module "peering_gce_instance" { environment = local.environment business_unit = local.business_unit project_suffix = "sample-peering" - region = var.instance_region + region = coalesce(var.instance_region, local.default_region) remote_state_bucket = var.remote_state_bucket } diff --git a/5-app-infra/business_unit_1/development/remote.tf b/5-app-infra/business_unit_1/development/remote.tf new file mode 100644 index 000000000..c2493dec1 --- /dev/null +++ b/5-app-infra/business_unit_1/development/remote.tf @@ -0,0 +1,28 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.terraform_remote_state.projects_env.outputs.default_region +} + +data "terraform_remote_state" "projects_env" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/projects/${local.business_unit}/${local.environment}" + } +} diff --git a/5-app-infra/business_unit_1/development/remote.tf.cloud.example b/5-app-infra/business_unit_1/development/remote.tf.cloud.example new file mode 100644 index 000000000..3a1223c7c --- /dev/null +++ b/5-app-infra/business_unit_1/development/remote.tf.cloud.example @@ -0,0 +1,24 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.tfe_outputs.projects.outputs.default_region +} + +data "tfe_outputs" "projects" { + organization = var.tfc_org_name + workspace = "4-projects" +} diff --git a/5-app-infra/business_unit_1/development/variables.tf b/5-app-infra/business_unit_1/development/variables.tf index 8e9bafd0a..8aa99e86c 100644 --- a/5-app-infra/business_unit_1/development/variables.tf +++ b/5-app-infra/business_unit_1/development/variables.tf @@ -17,6 +17,7 @@ variable "instance_region" { description = "The region where compute instance will be created. A subnetwork must exists in the instance region." type = string + default = null } variable "remote_state_bucket" { diff --git a/5-app-infra/business_unit_1/nonproduction/README.md b/5-app-infra/business_unit_1/nonproduction/README.md index 56d20b016..6809c65cf 100644 --- a/5-app-infra/business_unit_1/nonproduction/README.md +++ b/5-app-infra/business_unit_1/nonproduction/README.md @@ -3,7 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | n/a | yes | +| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | `null` | no | | remote\_state\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | ## Outputs diff --git a/5-app-infra/business_unit_1/nonproduction/main.tf b/5-app-infra/business_unit_1/nonproduction/main.tf index efab83f9a..76489f10d 100644 --- a/5-app-infra/business_unit_1/nonproduction/main.tf +++ b/5-app-infra/business_unit_1/nonproduction/main.tf @@ -25,7 +25,7 @@ module "base_shared_gce_instance" { environment = local.environment business_unit = local.business_unit project_suffix = "sample-base" - region = var.instance_region + region = coalesce(var.instance_region, local.default_region) remote_state_bucket = var.remote_state_bucket } @@ -35,6 +35,6 @@ module "peering_gce_instance" { environment = local.environment business_unit = local.business_unit project_suffix = "sample-peering" - region = var.instance_region + region = coalesce(var.instance_region, local.default_region) remote_state_bucket = var.remote_state_bucket } diff --git a/5-app-infra/business_unit_1/nonproduction/remote.tf b/5-app-infra/business_unit_1/nonproduction/remote.tf new file mode 100644 index 000000000..c2493dec1 --- /dev/null +++ b/5-app-infra/business_unit_1/nonproduction/remote.tf @@ -0,0 +1,28 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.terraform_remote_state.projects_env.outputs.default_region +} + +data "terraform_remote_state" "projects_env" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/projects/${local.business_unit}/${local.environment}" + } +} diff --git a/5-app-infra/business_unit_1/nonproduction/remote.tf.cloud.example b/5-app-infra/business_unit_1/nonproduction/remote.tf.cloud.example new file mode 100644 index 000000000..3a1223c7c --- /dev/null +++ b/5-app-infra/business_unit_1/nonproduction/remote.tf.cloud.example @@ -0,0 +1,24 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.tfe_outputs.projects.outputs.default_region +} + +data "tfe_outputs" "projects" { + organization = var.tfc_org_name + workspace = "4-projects" +} diff --git a/5-app-infra/business_unit_1/nonproduction/variables.tf b/5-app-infra/business_unit_1/nonproduction/variables.tf index 8e9bafd0a..8aa99e86c 100644 --- a/5-app-infra/business_unit_1/nonproduction/variables.tf +++ b/5-app-infra/business_unit_1/nonproduction/variables.tf @@ -17,6 +17,7 @@ variable "instance_region" { description = "The region where compute instance will be created. A subnetwork must exists in the instance region." type = string + default = null } variable "remote_state_bucket" { diff --git a/5-app-infra/business_unit_1/production/README.md b/5-app-infra/business_unit_1/production/README.md index 56d20b016..6809c65cf 100644 --- a/5-app-infra/business_unit_1/production/README.md +++ b/5-app-infra/business_unit_1/production/README.md @@ -3,7 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| -| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | n/a | yes | +| instance\_region | The region where compute instance will be created. A subnetwork must exists in the instance region. | `string` | `null` | no | | remote\_state\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes | ## Outputs diff --git a/5-app-infra/business_unit_1/production/main.tf b/5-app-infra/business_unit_1/production/main.tf index 544c94213..40b488e89 100644 --- a/5-app-infra/business_unit_1/production/main.tf +++ b/5-app-infra/business_unit_1/production/main.tf @@ -25,7 +25,7 @@ module "base_shared_gce_instance" { environment = local.environment business_unit = local.business_unit project_suffix = "sample-base" - region = var.instance_region + region = coalesce(var.instance_region, local.default_region) remote_state_bucket = var.remote_state_bucket } @@ -35,6 +35,6 @@ module "peering_gce_instance" { environment = local.environment business_unit = local.business_unit project_suffix = "sample-peering" - region = var.instance_region + region = coalesce(var.instance_region, local.default_region) remote_state_bucket = var.remote_state_bucket } diff --git a/5-app-infra/business_unit_1/production/remote.tf b/5-app-infra/business_unit_1/production/remote.tf new file mode 100644 index 000000000..4262266ce --- /dev/null +++ b/5-app-infra/business_unit_1/production/remote.tf @@ -0,0 +1,30 @@ +/** + * Copyright 2021 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.terraform_remote_state.projects_env.outputs.default_region +} + +data "terraform_remote_state" "projects_env" { + backend = "gcs" + + config = { + bucket = var.remote_state_bucket + prefix = "terraform/projects/${local.business_unit}/${local.environment}" + } +} + + diff --git a/5-app-infra/business_unit_1/production/remote.tf.cloud.example b/5-app-infra/business_unit_1/production/remote.tf.cloud.example new file mode 100644 index 000000000..3a1223c7c --- /dev/null +++ b/5-app-infra/business_unit_1/production/remote.tf.cloud.example @@ -0,0 +1,24 @@ +/** + * Copyright 2023 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +locals { + default_region = data.tfe_outputs.projects.outputs.default_region +} + +data "tfe_outputs" "projects" { + organization = var.tfc_org_name + workspace = "4-projects" +} diff --git a/5-app-infra/business_unit_1/production/variables.tf b/5-app-infra/business_unit_1/production/variables.tf index 8e9bafd0a..8aa99e86c 100644 --- a/5-app-infra/business_unit_1/production/variables.tf +++ b/5-app-infra/business_unit_1/production/variables.tf @@ -17,6 +17,7 @@ variable "instance_region" { description = "The region where compute instance will be created. A subnetwork must exists in the instance region." type = string + default = null } variable "remote_state_bucket" { diff --git a/5-app-infra/common.auto.example.tfvars b/5-app-infra/common.auto.example.tfvars index 7f83f05b6..8ba24df06 100644 --- a/5-app-infra/common.auto.example.tfvars +++ b/5-app-infra/common.auto.example.tfvars @@ -14,6 +14,6 @@ * limitations under the License. */ -instance_region = "us-central1" // should be one of the regions used to create network on step 3-networks +# instance_region = "us-central1" // should be one of the regions used to create network on step 3-networks remote_state_bucket = "REMOTE_STATE_BUCKET" diff --git a/build/int.cloudbuild.yaml b/build/int.cloudbuild.yaml index ed3be19a1..3d5d1a913 100644 --- a/build/int.cloudbuild.yaml +++ b/build/int.cloudbuild.yaml @@ -171,10 +171,7 @@ options: - 'TF_VAR_log_export_storage_force_destroy=true' - 'TF_VAR_domain_to_allow=test.blueprints.joonix.net' - 'TF_VAR_domain=test.blueprints.joonix.net.' - - 'TF_VAR_default_region=us-west1' - - 'TF_VAR_default_region1=us-west1' - - 'TF_VAR_default_region2=us-central1' - - 'TF_VAR_instance_region=us-west1' + - 'TF_VAR_instance_region=us-central1' - 'TF_IN_AUTOMATION=true' substitutions: _DOCKER_IMAGE_DEVELOPER_TOOLS: 'cft/developer-tools' diff --git a/helpers/foundation-deployer/global.tfvars.example b/helpers/foundation-deployer/global.tfvars.example index 662d32e52..be6a63911 100644 --- a/helpers/foundation-deployer/global.tfvars.example +++ b/helpers/foundation-deployer/global.tfvars.example @@ -31,9 +31,12 @@ validator_project_id = "EXISTING_PROJECT_ID" // 0-bootstrap inputs // https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/0-bootstrap/README.md#inputs -org_id = "REPLACE_ME" # format "000000000000" -billing_account = "REPLACE_ME" # format "000000-000000-000000" -default_region = "us-central1" +org_id = "REPLACE_ME" # format "000000000000" +billing_account = "REPLACE_ME" # format "000000-000000-000000" +default_region = "us-central1" +default_region_2 = "us-west1" +default_region_gcs = "US" +default_region_kms = "us" bucket_force_destroy = false bucket_tfstate_kms_force_destroy = false @@ -138,6 +141,8 @@ target_name_server_addresses = [ // 4-projects inputs // https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/4-projects/business_unit_1/production/README.md#inputs +// Can be used to override the default region set in 0-bootstrap +// See https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/4-projects/business_unit_1/production/README.md#outputs -projects_gcs_location = "US" -projects_kms_location = "us" +gcs_location = "US" +kms_location = "us" diff --git a/helpers/foundation-deployer/stages/apply.go b/helpers/foundation-deployer/stages/apply.go index 243473fde..cb3625b41 100644 --- a/helpers/foundation-deployer/stages/apply.go +++ b/helpers/foundation-deployer/stages/apply.go @@ -34,6 +34,9 @@ func DeployBootstrapStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, c Co bootstrapTfvars := BootstrapTfvars{ OrgID: tfvars.OrgID, DefaultRegion: tfvars.DefaultRegion, + DefaultRegion2: tfvars.DefaultRegion2, + DefaultRegionGCS: tfvars.DefaultRegionGCS, + DefaultRegionKMS: tfvars.DefaultRegionKMS, BillingAccount: tfvars.BillingAccount, ParentFolder: tfvars.ParentFolder, ProjectPrefix: tfvars.ProjectPrefix, diff --git a/helpers/foundation-deployer/stages/data.go b/helpers/foundation-deployer/stages/data.go index a640097b0..ab889921f 100644 --- a/helpers/foundation-deployer/stages/data.go +++ b/helpers/foundation-deployer/stages/data.go @@ -132,6 +132,9 @@ type GlobalTFVars struct { OrgID string `hcl:"org_id"` BillingAccount string `hcl:"billing_account"` DefaultRegion string `hcl:"default_region"` + DefaultRegion2 string `hcl:"default_region_2"` + DefaultRegionGCS string `hcl:"default_region_gcs"` + DefaultRegionKMS string `hcl:"default_region_kms"` ParentFolder *string `hcl:"parent_folder"` Domain string `hcl:"domain"` DomainsToAllow []string `hcl:"domains_to_allow"` @@ -194,6 +197,9 @@ type BootstrapTfvars struct { OrgID string `hcl:"org_id"` BillingAccount string `hcl:"billing_account"` DefaultRegion string `hcl:"default_region"` + DefaultRegion2 string `hcl:"default_region_2"` + DefaultRegionGCS string `hcl:"default_region_gcs"` + DefaultRegionKMS string `hcl:"default_region_kms"` ParentFolder *string `hcl:"parent_folder"` ProjectPrefix *string `hcl:"project_prefix"` FolderPrefix *string `hcl:"folder_prefix"` diff --git a/test/integration/networks/networks_test.go b/test/integration/networks/networks_test.go index 6461badff..1963af8b8 100644 --- a/test/integration/networks/networks_test.go +++ b/test/integration/networks/networks_test.go @@ -55,12 +55,12 @@ func getNetworkResourceNames(envCode string, networkMode string, firewallMode st "dns_zone_pkg_dev": fmt.Sprintf("dz-%s-shared-base-pkg-dev", envCode), "dns_zone_peering_zone": fmt.Sprintf("dz-%s-shared-base-to-dns-hub", envCode), "dns_policy_name": fmt.Sprintf("dp-%s-shared-base-default-policy", envCode), - "subnet_name1": fmt.Sprintf("sb-%s-shared-base-us-west1", envCode), - "subnet_name2": fmt.Sprintf("sb-%s-shared-base-us-central1", envCode), - "region1_router1": fmt.Sprintf("cr-%s-shared-base%s-us-west1-cr1", envCode, networkMode), - "region1_router2": fmt.Sprintf("cr-%s-shared-base%s-us-west1-cr2", envCode, networkMode), - "region2_router1": fmt.Sprintf("cr-%s-shared-base%s-us-central1-cr3", envCode, networkMode), - "region2_router2": fmt.Sprintf("cr-%s-shared-base%s-us-central1-cr4", envCode, networkMode), + "subnet_name1": fmt.Sprintf("sb-%s-shared-base-us-central1", envCode), + "subnet_name2": fmt.Sprintf("sb-%s-shared-base-us-west1", envCode), + "region1_router1": fmt.Sprintf("cr-%s-shared-base%s-us-central1-cr1", envCode, networkMode), + "region1_router2": fmt.Sprintf("cr-%s-shared-base%s-us-central1-cr2", envCode, networkMode), + "region2_router1": fmt.Sprintf("cr-%s-shared-base%s-us-west1-cr3", envCode, networkMode), + "region2_router2": fmt.Sprintf("cr-%s-shared-base%s-us-west1-cr4", envCode, networkMode), "firewall_policy": fmt.Sprintf("fp-%s-%s-base-firewalls", envCode, firewallMode), "fw_deny_all_egress": fmt.Sprintf("fw-%s-shared-base-65530-e-d-all-all-all", envCode), "fw_allow_api_egress": fmt.Sprintf("fw-%s-shared-base-1000-e-a-allow-google-apis-all-tcp-443", envCode), @@ -73,12 +73,12 @@ func getNetworkResourceNames(envCode string, networkMode string, firewallMode st "dns_zone_pkg_dev": fmt.Sprintf("dz-%s-shared-restricted-pkg-dev", envCode), "dns_zone_peering_zone": fmt.Sprintf("dz-%s-shared-restricted-to-dns-hub", envCode), "dns_policy_name": fmt.Sprintf("dp-%s-shared-restricted-default-policy", envCode), - "subnet_name1": fmt.Sprintf("sb-%s-shared-restricted-us-west1", envCode), - "subnet_name2": fmt.Sprintf("sb-%s-shared-restricted-us-central1", envCode), - "region1_router1": fmt.Sprintf("cr-%s-shared-restricted%s-us-west1-cr5", envCode, networkMode), - "region1_router2": fmt.Sprintf("cr-%s-shared-restricted%s-us-west1-cr6", envCode, networkMode), - "region2_router1": fmt.Sprintf("cr-%s-shared-restricted%s-us-central1-cr7", envCode, networkMode), - "region2_router2": fmt.Sprintf("cr-%s-shared-restricted%s-us-central1-cr8", envCode, networkMode), + "subnet_name1": fmt.Sprintf("sb-%s-shared-restricted-us-central1", envCode), + "subnet_name2": fmt.Sprintf("sb-%s-shared-restricted-us-west1", envCode), + "region1_router1": fmt.Sprintf("cr-%s-shared-restricted%s-us-central1-cr5", envCode, networkMode), + "region1_router2": fmt.Sprintf("cr-%s-shared-restricted%s-us-central1-cr6", envCode, networkMode), + "region2_router1": fmt.Sprintf("cr-%s-shared-restricted%s-us-west1-cr7", envCode, networkMode), + "region2_router2": fmt.Sprintf("cr-%s-shared-restricted%s-us-west1-cr8", envCode, networkMode), "firewall_policy": fmt.Sprintf("fp-%s-%s-restricted-firewalls", envCode, firewallMode), "fw_deny_all_egress": fmt.Sprintf("fw-%s-shared-restricted-65530-e-d-all-all-all", envCode), "fw_allow_api_egress": fmt.Sprintf("fw-%s-shared-restricted-1000-e-a-allow-google-apis-all-tcp-443", envCode), @@ -403,16 +403,16 @@ func TestNetworks(t *testing.T) { assert.Equal(globalAddressName, globalAddress.Get("name").String(), fmt.Sprintf("global address %s should exist", globalAddressName)) subnetName1 := networkNames[networkType]["subnet_name1"] - usWest1Range := cidrRanges[envName][networkType][0] - subnet1 := gcloud.Runf(t, "compute networks subnets describe %s --region us-west1 --project %s --impersonate-service-account %s", subnetName1, projectID, terraformSA) + usCentral1Range := cidrRanges[envName][networkType][0] + subnet1 := gcloud.Runf(t, "compute networks subnets describe %s --region us-central1 --project %s --impersonate-service-account %s", subnetName1, projectID, terraformSA) assert.Equal(subnetName1, subnet1.Get("name").String(), fmt.Sprintf("subnet %s should exist", subnetName1)) - assert.Equal(usWest1Range, subnet1.Get("ipCidrRange").String(), fmt.Sprintf("IP CIDR range %s should be", usWest1Range)) + assert.Equal(usCentral1Range, subnet1.Get("ipCidrRange").String(), fmt.Sprintf("IP CIDR range %s should be", usCentral1Range)) subnetName2 := networkNames[networkType]["subnet_name2"] - usCentral1Range := cidrRanges[envName][networkType][1] - subnet2 := gcloud.Runf(t, "compute networks subnets describe %s --region us-central1 --project %s --impersonate-service-account %s", subnetName2, projectID, terraformSA) + usWest1Range := cidrRanges[envName][networkType][1] + subnet2 := gcloud.Runf(t, "compute networks subnets describe %s --region us-west1 --project %s --impersonate-service-account %s", subnetName2, projectID, terraformSA) assert.Equal(subnetName2, subnet2.Get("name").String(), fmt.Sprintf("subnet %s should exist", subnetName2)) - assert.Equal(usCentral1Range, subnet2.Get("ipCidrRange").String(), fmt.Sprintf("IP CIDR range %s should be", usCentral1Range)) + assert.Equal(usWest1Range, subnet2.Get("ipCidrRange").String(), fmt.Sprintf("IP CIDR range %s should be", usWest1Range)) denyAllEgressName := networkNames[networkType]["fw_deny_all_egress"] denyAllEgressRule := gcloud.Runf(t, "compute network-firewall-policies rules describe 65530 --firewall-policy %s --global-firewall-policy --project %s --impersonate-service-account %s", networkNames[networkType]["firewall_policy"], projectID, terraformSA).Array()[0] @@ -437,19 +437,19 @@ func TestNetworks(t *testing.T) { }{ { router: "region1_router1", - region: "us-west1", + region: "us-central1", }, { router: "region1_router2", - region: "us-west1", + region: "us-central1", }, { router: "region2_router1", - region: "us-central1", + region: "us-west1", }, { router: "region2_router2", - region: "us-central1", + region: "us-west1", }, } { diff --git a/test/integration/projects/projects_test.go b/test/integration/projects/projects_test.go index fb6302967..2812a50a7 100644 --- a/test/integration/projects/projects_test.go +++ b/test/integration/projects/projects_test.go @@ -215,7 +215,7 @@ func TestProjects(t *testing.T) { peering := gcloud.Runf(t, "compute networks peerings list --project %s", projectID).Array()[0] assert.Contains(peering.Get("peerings.0.network").String(), tt.baseNetwork, "should have a peering network") - instanceRegion := utils.ValFromEnv(t, "TF_VAR_instance_region") + instanceRegion := terraform.OutputMap(t, bootstrap.GetTFOptions(), "common_config")["default_region"] peeringSubnetworkSelfLink := projects.GetStringOutput("peering_subnetwork_self_link") peeringSubnetworkSelfLinkSplitted := strings.Split(peeringSubnetworkSelfLink, "/") peering_subnetwork_name := peeringSubnetworkSelfLinkSplitted[len(peeringSubnetworkSelfLinkSplitted)-1] diff --git a/test/integration/shared/shared_test.go b/test/integration/shared/shared_test.go index ab42dfdae..8102b7163 100644 --- a/test/integration/shared/shared_test.go +++ b/test/integration/shared/shared_test.go @@ -109,14 +109,14 @@ func TestShared(t *testing.T) { region string }{ { - name: "sb-net-dns-us-central1", + name: "sb-net-dns-us-west1", cidrRange: "172.16.0.128/25", - region: "us-central1", + region: "us-west1", }, { - name: "sb-net-dns-us-west1", + name: "sb-net-dns-us-central1", cidrRange: "172.16.0.0/25", - region: "us-west1", + region: "us-central1", }, } { sub := gcloud.Runf(t, "compute networks subnets describe %s --region %s --project %s", subnet.name, subnet.region, projectID) @@ -131,20 +131,20 @@ func TestShared(t *testing.T) { region string }{ { - name: "cr-net-dns-us-west1-cr1", - region: "us-west1", + name: "cr-net-dns-us-central1-cr1", + region: "us-central1", }, { - name: "cr-net-dns-us-west1-cr2", - region: "us-west1", + name: "cr-net-dns-us-central1-cr2", + region: "us-central1", }, { - name: "cr-net-dns-us-central1-cr3", - region: "us-central1", + name: "cr-net-dns-us-west1-cr3", + region: "us-west1", }, { - name: "cr-net-dns-us-central1-cr4", - region: "us-central1", + name: "cr-net-dns-us-west1-cr4", + region: "us-west1", }, } { computeRouter := gcloud.Runf(t, "compute routers describe %s --region %s --project %s", router.name, router.region, projectID)