diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md index 2b5b5c58c..a9941e367 100644 --- a/0-bootstrap/README.md +++ b/0-bootstrap/README.md @@ -361,12 +361,14 @@ Each step has instructions for this change. | 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\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | 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
})
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 |
| org\_id | GCP Organization ID | `string` | n/a | yes |
| org\_policy\_admin\_role | Additional Org Policy Admin role for admin group. You can use this for testing purposes. | `bool` | `false` | no |
| parent\_folder | Optional - for an organization with existing projects or for development/validation. It will place all the example foundation resources under the provided folder instead of the root organization. The value is the numeric folder ID. The folder must already exist. | `string` | `""` | no |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no |
## Outputs
diff --git a/0-bootstrap/cb.tf b/0-bootstrap/cb.tf
index 8c2ba91b4..ef7e922b4 100644
--- a/0-bootstrap/cb.tf
+++ b/0-bootstrap/cb.tf
@@ -70,7 +70,7 @@ resource "random_string" "suffix" {
module "gcp_projects_state_bucket" {
source = "terraform-google-modules/cloud-storage/google//modules/simple_bucket"
- version = "~> 6.0"
+ version = "~> 8.0"
name = "${var.bucket_prefix}-${module.seed_bootstrap.seed_project_id}-gcp-projects-tfstate"
project_id = module.seed_bootstrap.seed_project_id
@@ -86,7 +86,7 @@ module "gcp_projects_state_bucket" {
module "tf_source" {
source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_source"
- version = "~> 8.0"
+ version = "~> 9.0"
org_id = var.org_id
folder_id = google_folder.bootstrap.id
@@ -96,6 +96,8 @@ module "tf_source" {
group_org_admins = var.groups.required_groups.group_org_admins
buckets_force_destroy = var.bucket_force_destroy
+ project_deletion_policy = var.project_deletion_policy
+
activate_apis = [
"serviceusage.googleapis.com",
"servicenetworking.googleapis.com",
@@ -134,6 +136,15 @@ module "tf_source" {
depends_on = [module.seed_bootstrap]
}
+resource "google_project_service_identity" "workflows_identity" {
+ provider = google-beta
+
+ project = module.tf_source.cloudbuild_project_id
+ service = "workflows.googleapis.com"
+
+ depends_on = [module.tf_source]
+}
+
module "tf_private_pool" {
source = "./modules/cb-private-pool"
@@ -155,7 +166,7 @@ module "tf_private_pool" {
module "tf_cloud_builder" {
source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_builder"
- version = "~> 8.0"
+ version = "~> 9.0"
project_id = module.tf_source.cloudbuild_project_id
dockerfile_repo_uri = module.tf_source.csr_repos[local.cloudbuilder_repo].url
@@ -206,7 +217,7 @@ module "build_terraform_image" {
module "tf_workspace" {
source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace"
- version = "~> 8.0"
+ version = "~> 9.0"
for_each = local.granular_sa
project_id = module.tf_source.cloudbuild_project_id
diff --git a/0-bootstrap/github.tf.example b/0-bootstrap/github.tf.example
index 7f5a0e3f3..df996af94 100644
--- a/0-bootstrap/github.tf.example
+++ b/0-bootstrap/github.tf.example
@@ -70,7 +70,7 @@ locals {
module "gh_cicd" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
name = "${var.project_prefix}-b-cicd-wif-gh"
random_project_id = true
@@ -87,6 +87,8 @@ module "gh_cicd" {
"cloudresourcemanager.googleapis.com",
"iamcredentials.googleapis.com",
]
+
+ deletion_policy = var.project_deletion_policy
}
module "gh_oidc" {
diff --git a/0-bootstrap/gitlab.tf.example b/0-bootstrap/gitlab.tf.example
index 579e84b21..1f0346cfc 100644
--- a/0-bootstrap/gitlab.tf.example
+++ b/0-bootstrap/gitlab.tf.example
@@ -81,7 +81,7 @@ provider "gitlab" {
module "gitlab_cicd" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
name = "${var.project_prefix}-b-cicd-wif-gl"
random_project_id = true
@@ -100,8 +100,9 @@ module "gitlab_cicd" {
"sts.googleapis.com",
"dns.googleapis.com",
"secretmanager.googleapis.com",
-
]
+
+ deletion_policy = var.project_deletion_policy
}
module "gitlab_oidc" {
diff --git a/0-bootstrap/groups.tf b/0-bootstrap/groups.tf
index 6f9a8d160..aadb18ece 100644
--- a/0-bootstrap/groups.tf
+++ b/0-bootstrap/groups.tf
@@ -34,7 +34,7 @@ data "google_organization" "org" {
module "required_group" {
source = "terraform-google-modules/group/google"
- version = "~> 0.6"
+ version = "~> 0.7"
for_each = local.required_groups_to_create
id = each.value
@@ -46,7 +46,7 @@ module "required_group" {
module "optional_group" {
source = "terraform-google-modules/group/google"
- version = "~> 0.6"
+ version = "~> 0.7"
for_each = local.optional_groups_to_create
id = each.value
diff --git a/0-bootstrap/jenkins.tf.example b/0-bootstrap/jenkins.tf.example
index 7e9413ffb..8a17ad374 100644
--- a/0-bootstrap/jenkins.tf.example
+++ b/0-bootstrap/jenkins.tf.example
@@ -46,6 +46,7 @@ module "jenkins_bootstrap" {
tunnel0_bgp_session_range = var.tunnel0_bgp_session_range
tunnel1_bgp_peer_address = var.tunnel1_bgp_peer_address
tunnel1_bgp_session_range = var.tunnel1_bgp_session_range
+ project_deletion_policy = var.project_deletion_policy
}
resource "google_organization_iam_member" "org_jenkins_sa_browser" {
diff --git a/0-bootstrap/main.tf b/0-bootstrap/main.tf
index f61eb8c77..1063e58fe 100644
--- a/0-bootstrap/main.tf
+++ b/0-bootstrap/main.tf
@@ -35,13 +35,14 @@ locals {
}
resource "google_folder" "bootstrap" {
- display_name = "${var.folder_prefix}-bootstrap"
- parent = local.parent
+ display_name = "${var.folder_prefix}-bootstrap"
+ parent = local.parent
+ deletion_protection = var.folder_deletion_protection
}
module "seed_bootstrap" {
source = "terraform-google-modules/bootstrap/google"
- version = "~> 8.0"
+ version = "~> 9.0"
org_id = var.org_id
folder_id = google_folder.bootstrap.id
@@ -61,6 +62,7 @@ module "seed_bootstrap" {
encrypt_gcs_bucket_tfstate = true
key_rotation_period = "7776000s"
kms_prevent_destroy = !var.bucket_tfstate_kms_force_destroy
+ project_deletion_policy = var.project_deletion_policy
project_labels = {
environment = "bootstrap"
diff --git a/0-bootstrap/modules/gitlab-oidc/versions.tf b/0-bootstrap/modules/gitlab-oidc/versions.tf
index dc2e4b617..0d9e65818 100644
--- a/0-bootstrap/modules/gitlab-oidc/versions.tf
+++ b/0-bootstrap/modules/gitlab-oidc/versions.tf
@@ -20,7 +20,7 @@ terraform {
google = {
source = "hashicorp/google"
- version = ">= 3.64, < 6"
+ version = ">= 3.64, < 7"
}
}
diff --git a/0-bootstrap/modules/jenkins-agent/README.md b/0-bootstrap/modules/jenkins-agent/README.md
index 09f72a5aa..10c713ea4 100644
--- a/0-bootstrap/modules/jenkins-agent/README.md
+++ b/0-bootstrap/modules/jenkins-agent/README.md
@@ -68,6 +68,7 @@ module "jenkins_bootstrap" {
| on\_prem\_vpn\_public\_ip\_address | The public IP Address of the Jenkins Controller. | `string` | n/a | yes |
| on\_prem\_vpn\_public\_ip\_address2 | The secondpublic IP Address of the Jenkins Controller. | `string` | n/a | yes |
| org\_id | GCP Organization ID | `string` | n/a | yes |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| project\_labels | Labels to apply to the project. | `map(string)` | `{}` | no |
| project\_prefix | Name prefix to use for projects created. | `string` | `"prj"` | no |
| router\_asn | BGP ASN for cloud routes. | `number` | `"64515"` | no |
diff --git a/0-bootstrap/modules/jenkins-agent/main.tf b/0-bootstrap/modules/jenkins-agent/main.tf
index d18397c6b..c9651b743 100644
--- a/0-bootstrap/modules/jenkins-agent/main.tf
+++ b/0-bootstrap/modules/jenkins-agent/main.tf
@@ -29,7 +29,7 @@ resource "random_id" "suffix" {
*******************************************/
module "cicd_project" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
name = local.cicd_project_name
random_project_id = true
@@ -40,6 +40,8 @@ module "cicd_project" {
billing_account = var.billing_account
activate_apis = local.activate_apis
labels = var.project_labels
+
+ deletion_policy = var.project_deletion_policy
}
/******************************************
diff --git a/0-bootstrap/modules/jenkins-agent/variables.tf b/0-bootstrap/modules/jenkins-agent/variables.tf
index 13c90a059..80b1f53db 100644
--- a/0-bootstrap/modules/jenkins-agent/variables.tf
+++ b/0-bootstrap/modules/jenkins-agent/variables.tf
@@ -39,6 +39,12 @@ variable "default_region" {
default = "us-central1"
}
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
+
/* ----------------------------------------
Specific to CICD Project
---------------------------------------- */
diff --git a/0-bootstrap/modules/tfc-agent-gke/main.tf b/0-bootstrap/modules/tfc-agent-gke/main.tf
index 4100c3611..2e631e3fd 100644
--- a/0-bootstrap/modules/tfc-agent-gke/main.tf
+++ b/0-bootstrap/modules/tfc-agent-gke/main.tf
@@ -96,7 +96,7 @@ resource "google_service_account" "tfc_agent_service_account" {
module "tfc_agent_cluster" {
source = "terraform-google-modules/kubernetes-engine/google//modules/beta-autopilot-private-cluster/"
- version = "~> 31.0"
+ version = "~> 34.0"
project_id = var.project_id
region = var.region
@@ -394,7 +394,7 @@ resource "google_dns_policy" "default_policy" {
module "hub" {
source = "terraform-google-modules/kubernetes-engine/google//modules/fleet-membership"
- version = "~> 31.0"
+ version = "~> 34.0"
project_id = var.project_id
location = var.region
diff --git a/0-bootstrap/modules/tfc-agent-gke/versions.tf b/0-bootstrap/modules/tfc-agent-gke/versions.tf
index 2ccf6ddc9..c3c6eeced 100644
--- a/0-bootstrap/modules/tfc-agent-gke/versions.tf
+++ b/0-bootstrap/modules/tfc-agent-gke/versions.tf
@@ -20,7 +20,7 @@ terraform {
google = {
source = "hashicorp/google"
- version = ">= 4.3.0, < 6"
+ version = ">= 4.3.0, < 7"
}
kubernetes = {
diff --git a/0-bootstrap/terraform_cloud.tf.example b/0-bootstrap/terraform_cloud.tf.example
index ab999e239..27d9e05a8 100644
--- a/0-bootstrap/terraform_cloud.tf.example
+++ b/0-bootstrap/terraform_cloud.tf.example
@@ -230,7 +230,7 @@ resource "tfe_run_trigger" "projects_bu2_shared_production" {
module "tfc_cicd" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
name = "${var.project_prefix}-b-cicd-wif-tfc"
random_project_id = true
@@ -251,6 +251,8 @@ module "tfc_cicd" {
"gkehub.googleapis.com",
"connectgateway.googleapis.com"
]
+
+ deletion_policy = var.project_deletion_policy
}
module "tfc-oidc" {
diff --git a/0-bootstrap/variables.tf b/0-bootstrap/variables.tf
index 39b993abb..db7e27c65 100644
--- a/0-bootstrap/variables.tf
+++ b/0-bootstrap/variables.tf
@@ -90,6 +90,18 @@ variable "bucket_tfstate_kms_force_destroy" {
default = false
}
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
+
+variable "folder_deletion_protection" {
+ description = "Prevent Terraform from destroying or recreating the folder."
+ type = string
+ default = true
+}
+
/* ----------------------------------------
Specific to Groups creation
---------------------------------------- */
diff --git a/0-bootstrap/versions.tf b/0-bootstrap/versions.tf
index ee8f24e58..17dac8a60 100644
--- a/0-bootstrap/versions.tf
+++ b/0-bootstrap/versions.tf
@@ -20,7 +20,13 @@ terraform {
google = {
// version 4.31.0 removed because of issue https://github.com/hashicorp/terraform-provider-google/issues/12226
source = "hashicorp/google"
- version = ">= 3.50, != 4.31.0"
+ version = ">= 3.50, != 4.31.0, <= 6.10"
+ }
+
+ google-beta = {
+ // version 4.31.0 removed because of issue https://github.com/hashicorp/terraform-provider-google/issues/12226
+ source = "hashicorp/google-beta"
+ version = ">= 3.50, != 4.31.0, <= 6.10"
}
// Un-comment gitlab required_providers when using gitlab CI/CD
diff --git a/1-org/envs/shared/README.md b/1-org/envs/shared/README.md
index e260c67ca..e12dc5bcf 100644
--- a/1-org/envs/shared/README.md
+++ b/1-org/envs/shared/README.md
@@ -12,12 +12,14 @@
| enforce\_allowed\_worker\_pools | Whether to enforce the organization policy restriction on allowed worker pools for Cloud Build. | `bool` | `false` | no |
| essential\_contacts\_domains\_to\_allow | The list of domains that email addresses added to Essential Contacts can have. | `list(string)` | n/a | yes |
| essential\_contacts\_language | Essential Contacts preferred language for notifications, as a ISO 639-1 language code. See [Supported languages](https://cloud.google.com/resource-manager/docs/managing-notification-contacts#supported-languages) for a list of supported languages. | `string` | `"en"` | no |
+| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | no |
| gcp\_groups | Groups to grant specific roles in the Organization.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` | `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.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_export_budget_amount = optional(number, 1000)
org_billing_export_alert_spent_percents = optional(list(number), [1.2])
org_billing_export_alert_pubsub_topic = optional(string, null)
org_billing_export_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
org_audit_logs_budget_amount = optional(number, 1000)
org_audit_logs_alert_spent_percents = optional(list(number), [1.2])
org_audit_logs_alert_pubsub_topic = optional(string, null)
org_audit_logs_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
common_kms_budget_amount = optional(number, 1000)
common_kms_alert_spent_percents = optional(list(number), [1.2])
common_kms_alert_pubsub_topic = optional(string, null)
common_kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
scc_notifications_budget_amount = optional(number, 1000)
scc_notifications_alert_spent_percents = optional(list(number), [1.2])
scc_notifications_alert_pubsub_topic = optional(string, null)
scc_notifications_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
}) | `{}` | no |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes |
| scc\_notification\_filter | Filter used to create the Security Command Center Notification, you can see more details on how to create filters in https://cloud.google.com/security-command-center/docs/how-to-api-filter-notifications#create-filter | `string` | `"state = \"ACTIVE\""` | no |
| scc\_notification\_name | Name of the Security Command Center Notification. It must be unique in the organization. Run `gcloud scc notifications describe object({
enabled = optional(bool, false)
location = optional(string, "us-central1")
display_name = optional(string, "FEDRAMP-MODERATE")
compliance_regime = optional(string, "FEDRAMP_MODERATE")
resource_type = optional(string, "CONSUMER_FOLDER")
}) | `{}` | no |
| env | The environment to prepare (ex. development) | `string` | n/a | yes |
| environment\_code | A short form of the folder level resources (environment) within the Google Cloud organization (ex. d). | `string` | n/a | yes |
+| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | no |
| project\_budget | Budget configuration for projects.object({
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_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")
secret_budget_amount = optional(number, 1000)
secret_alert_spent_percents = optional(list(number), [1.2])
secret_alert_pubsub_topic = optional(string, null)
secret_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
kms_budget_amount = optional(number, 1000)
kms_alert_spent_percents = optional(list(number), [1.2])
kms_alert_pubsub_topic = optional(string, null)
kms_budget_alert_spend_basis = optional(string, "FORECASTED_SPEND")
}) | `{}` | no |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes |
| tfc\_org\_name | Name of the TFC organization | `string` | n/a | yes |
diff --git a/2-environments/modules/env_baseline/folders.tf b/2-environments/modules/env_baseline/folders.tf
index 7e05471ce..61c8f6c64 100644
--- a/2-environments/modules/env_baseline/folders.tf
+++ b/2-environments/modules/env_baseline/folders.tf
@@ -19,8 +19,9 @@
*****************************************/
resource "google_folder" "env" {
- display_name = "${local.folder_prefix}-${var.env}"
- parent = local.parent
+ display_name = "${local.folder_prefix}-${var.env}"
+ parent = local.parent
+ deletion_protection = var.folder_deletion_protection
}
resource "time_sleep" "wait_60_seconds" {
diff --git a/2-environments/modules/env_baseline/kms.tf b/2-environments/modules/env_baseline/kms.tf
index e6e4d992f..01dc42f26 100644
--- a/2-environments/modules/env_baseline/kms.tf
+++ b/2-environments/modules/env_baseline/kms.tf
@@ -21,7 +21,7 @@
module "env_kms" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
random_project_id = true
random_project_id_length = 4
@@ -33,6 +33,7 @@ module "env_kms" {
disable_services_on_destroy = false
depends_on = [time_sleep.wait_60_seconds]
activate_apis = ["logging.googleapis.com", "cloudkms.googleapis.com", "billingbudgets.googleapis.com"]
+ deletion_policy = var.project_deletion_policy
labels = {
environment = var.env
diff --git a/2-environments/modules/env_baseline/secrets.tf b/2-environments/modules/env_baseline/secrets.tf
index fa875c67a..6ff24a4ec 100644
--- a/2-environments/modules/env_baseline/secrets.tf
+++ b/2-environments/modules/env_baseline/secrets.tf
@@ -21,7 +21,7 @@
module "env_secrets" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
random_project_id = true
random_project_id_length = 4
@@ -33,6 +33,7 @@ module "env_secrets" {
disable_services_on_destroy = false
depends_on = [time_sleep.wait_60_seconds]
activate_apis = ["logging.googleapis.com", "secretmanager.googleapis.com"]
+ deletion_policy = var.project_deletion_policy
labels = {
environment = var.env
diff --git a/2-environments/modules/env_baseline/variables.tf b/2-environments/modules/env_baseline/variables.tf
index 400479c0e..81ab12a83 100644
--- a/2-environments/modules/env_baseline/variables.tf
+++ b/2-environments/modules/env_baseline/variables.tf
@@ -81,3 +81,15 @@ variable "assured_workload_configuration" {
})
default = {}
}
+
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
+
+variable "folder_deletion_protection" {
+ description = "Prevent Terraform from destroying or recreating the folder."
+ type = string
+ default = true
+}
diff --git a/3-networks-hub-and-spoke/modules/transitivity/main.tf b/3-networks-hub-and-spoke/modules/transitivity/main.tf
index 92cafdf2f..f2e0cff90 100644
--- a/3-networks-hub-and-spoke/modules/transitivity/main.tf
+++ b/3-networks-hub-and-spoke/modules/transitivity/main.tf
@@ -37,7 +37,7 @@ module "service_account" {
module "templates" {
source = "terraform-google-modules/vm/google//modules/instance_template"
- version = "~> 11.0"
+ version = "~> 12.0"
for_each = toset(var.regions)
can_ip_forward = true
@@ -65,7 +65,7 @@ module "templates" {
module "migs" {
source = "terraform-google-modules/vm/google//modules/mig"
- version = "~> 11.1"
+ version = "~> 12.1"
for_each = toset(var.regions)
project_id = var.project_id
@@ -91,7 +91,7 @@ module "migs" {
module "ilbs" {
source = "GoogleCloudPlatform/lb-internal/google"
- version = "~> 6.0"
+ version = "~> 7.0"
for_each = toset(var.regions)
region = each.key
@@ -108,7 +108,10 @@ module "ilbs" {
target_tags = null
create_backend_firewall = false
backends = [
- { group = module.migs[each.key].instance_group, description = "" },
+ {
+ group = module.migs[each.key].instance_group,
+ description = ""
+ },
]
health_check = {
diff --git a/4-projects/business_unit_1/development/README.md b/4-projects/business_unit_1/development/README.md
index e1fa6e324..9d723d711 100644
--- a/4-projects/business_unit_1/development/README.md
+++ b/4-projects/business_unit_1/development/README.md
@@ -3,11 +3,13 @@
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
+| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | 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 |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes |
| tfc\_org\_name | Name of the TFC organization. | `string` | `""` | no |
diff --git a/4-projects/business_unit_1/development/main.tf b/4-projects/business_unit_1/development/main.tf
index b2efde30d..1ad8a4131 100644
--- a/4-projects/business_unit_1/development/main.tf
+++ b/4-projects/business_unit_1/development/main.tf
@@ -34,4 +34,6 @@ module "env" {
peering_iap_fw_rules_enabled = true
subnet_region = coalesce(var.instance_region, local.default_region)
subnet_ip_range = "10.3.64.0/21"
+ project_deletion_policy = var.project_deletion_policy
+ folder_deletion_protection = var.folder_deletion_protection
}
diff --git a/4-projects/business_unit_1/development/variables.tf b/4-projects/business_unit_1/development/variables.tf
index 0b055e98f..7add57dfc 100644
--- a/4-projects/business_unit_1/development/variables.tf
+++ b/4-projects/business_unit_1/development/variables.tf
@@ -56,3 +56,15 @@ variable "instance_region" {
type = string
default = null
}
+
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
+
+variable "folder_deletion_protection" {
+ description = "Prevent Terraform from destroying or recreating the folder."
+ type = string
+ default = true
+}
diff --git a/4-projects/business_unit_1/nonproduction/README.md b/4-projects/business_unit_1/nonproduction/README.md
index e1fa6e324..9d723d711 100644
--- a/4-projects/business_unit_1/nonproduction/README.md
+++ b/4-projects/business_unit_1/nonproduction/README.md
@@ -3,11 +3,13 @@
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
+| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | 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 |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes |
| tfc\_org\_name | Name of the TFC organization. | `string` | `""` | no |
diff --git a/4-projects/business_unit_1/nonproduction/main.tf b/4-projects/business_unit_1/nonproduction/main.tf
index ef954c892..b8a4514b7 100644
--- a/4-projects/business_unit_1/nonproduction/main.tf
+++ b/4-projects/business_unit_1/nonproduction/main.tf
@@ -34,4 +34,6 @@ module "env" {
peering_iap_fw_rules_enabled = true
subnet_region = coalesce(var.instance_region, local.default_region)
subnet_ip_range = "10.3.128.0/21"
+ project_deletion_policy = var.project_deletion_policy
+ folder_deletion_protection = var.folder_deletion_protection
}
diff --git a/4-projects/business_unit_1/nonproduction/variables.tf b/4-projects/business_unit_1/nonproduction/variables.tf
index 0b055e98f..7add57dfc 100644
--- a/4-projects/business_unit_1/nonproduction/variables.tf
+++ b/4-projects/business_unit_1/nonproduction/variables.tf
@@ -56,3 +56,15 @@ variable "instance_region" {
type = string
default = null
}
+
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
+
+variable "folder_deletion_protection" {
+ description = "Prevent Terraform from destroying or recreating the folder."
+ type = string
+ default = true
+}
diff --git a/4-projects/business_unit_1/production/README.md b/4-projects/business_unit_1/production/README.md
index e1fa6e324..9d723d711 100644
--- a/4-projects/business_unit_1/production/README.md
+++ b/4-projects/business_unit_1/production/README.md
@@ -3,11 +3,13 @@
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
+| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | 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 |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes |
| tfc\_org\_name | Name of the TFC organization. | `string` | `""` | no |
diff --git a/4-projects/business_unit_1/production/main.tf b/4-projects/business_unit_1/production/main.tf
index cdc136052..4bf4b9f74 100644
--- a/4-projects/business_unit_1/production/main.tf
+++ b/4-projects/business_unit_1/production/main.tf
@@ -34,4 +34,6 @@ module "env" {
peering_iap_fw_rules_enabled = true
subnet_region = coalesce(var.instance_region, local.default_region)
subnet_ip_range = "10.3.192.0/21"
+ project_deletion_policy = var.project_deletion_policy
+ folder_deletion_protection = var.folder_deletion_protection
}
diff --git a/4-projects/business_unit_1/production/variables.tf b/4-projects/business_unit_1/production/variables.tf
index 0b055e98f..7add57dfc 100644
--- a/4-projects/business_unit_1/production/variables.tf
+++ b/4-projects/business_unit_1/production/variables.tf
@@ -56,3 +56,15 @@ variable "instance_region" {
type = string
default = null
}
+
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
+
+variable "folder_deletion_protection" {
+ description = "Prevent Terraform from destroying or recreating the folder."
+ type = string
+ default = true
+}
diff --git a/4-projects/business_unit_1/shared/README.md b/4-projects/business_unit_1/shared/README.md
index 9515329eb..011c44625 100644
--- a/4-projects/business_unit_1/shared/README.md
+++ b/4-projects/business_unit_1/shared/README.md
@@ -5,6 +5,7 @@
|------|-------------|------|---------|:--------:|
| default\_region | Default region to create resources where applicable. | `string` | `"us-central1"` | no |
| project\_budget | Budget configuration.object({
budget_amount = optional(number, 1000)
alert_spent_percents = optional(list(number), [1.2])
alert_pubsub_topic = optional(string, null)
alert_spend_basis = optional(string, "FORECASTED_SPEND")
}) | `{}` | no |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes |
| tfc\_org\_name | Name of the TFC organization | `string` | `""` | no |
diff --git a/4-projects/business_unit_1/shared/example_infra_pipeline.tf b/4-projects/business_unit_1/shared/example_infra_pipeline.tf
index 7b09e6cd6..013b80bd4 100644
--- a/4-projects/business_unit_1/shared/example_infra_pipeline.tf
+++ b/4-projects/business_unit_1/shared/example_infra_pipeline.tf
@@ -28,6 +28,9 @@ module "app_infra_cloudbuild_project" {
environment = "common"
project_budget = var.project_budget
project_prefix = local.project_prefix
+
+ project_deletion_policy = var.project_deletion_policy
+
activate_apis = [
"cloudbuild.googleapis.com",
"sourcerepo.googleapis.com",
diff --git a/4-projects/business_unit_1/shared/variables.tf b/4-projects/business_unit_1/shared/variables.tf
index 5f08bcddf..b372391ef 100644
--- a/4-projects/business_unit_1/shared/variables.tf
+++ b/4-projects/business_unit_1/shared/variables.tf
@@ -47,3 +47,9 @@ variable "tfc_org_name" {
type = string
default = ""
}
+
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
diff --git a/4-projects/modules/base_env/README.md b/4-projects/modules/base_env/README.md
index 70d08bc55..25653ac3c 100644
--- a/4-projects/modules/base_env/README.md
+++ b/4-projects/modules/base_env/README.md
@@ -7,6 +7,7 @@
| business\_unit | The business (ex. business\_unit\_1). | `string` | n/a | yes |
| env | The environment to prepare (ex. development). | `string` | n/a | yes |
| firewall\_enable\_logging | Toggle firewall logging for VPC Firewalls. | `bool` | `true` | no |
+| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `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 |
@@ -20,6 +21,7 @@
| 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 |
| project\_budget | Budget configuration.object({
budget_amount = optional(number, 1000)
alert_spent_percents = optional(list(number), [1.2])
alert_pubsub_topic = optional(string, null)
alert_spend_basis = optional(string, "FORECASTED_SPEND")
}) | `{}` | no |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| remote\_state\_bucket | Backend bucket to load Terraform Remote State Data from previous steps. | `string` | n/a | yes |
| subnet\_ip\_range | IP range for the peered subnetwork. If "peering\_iap\_fw\_rules\_enabled" is true, this field should not be null. | `string` | `null` | no |
| subnet\_region | Region which the peered subnet will be created. If "peering\_iap\_fw\_rules\_enabled" is true, this field should not be null. | `string` | `null` | no |
diff --git a/4-projects/modules/base_env/business_unit_folder.tf b/4-projects/modules/base_env/business_unit_folder.tf
index 68a98ea2f..a379e82d9 100644
--- a/4-projects/modules/base_env/business_unit_folder.tf
+++ b/4-projects/modules/base_env/business_unit_folder.tf
@@ -19,6 +19,7 @@ locals {
}
resource "google_folder" "env_business_unit" {
- display_name = local.env_business_unit_folder_name
- parent = local.env_folder_name
+ display_name = local.env_business_unit_folder_name
+ parent = local.env_folder_name
+ deletion_protection = var.folder_deletion_protection
}
diff --git a/4-projects/modules/base_env/example_base_shared_vpc_project.tf b/4-projects/modules/base_env/example_base_shared_vpc_project.tf
index 2b7c5e7ba..03741b6a2 100644
--- a/4-projects/modules/base_env/example_base_shared_vpc_project.tf
+++ b/4-projects/modules/base_env/example_base_shared_vpc_project.tf
@@ -29,6 +29,8 @@ module "base_shared_vpc_project" {
enable_cloudbuild_deploy = local.enable_cloudbuild_deploy
app_infra_pipeline_service_accounts = local.app_infra_pipeline_service_accounts
+ project_deletion_policy = var.project_deletion_policy
+
// The roles defined in "sa_roles" will be used to grant the necessary permissions
// to deploy the resources, a Compute Engine instance for each environment, defined
// in 5-app-infra step (5-app-infra/modules/env_base/main.tf).
@@ -47,7 +49,8 @@ module "base_shared_vpc_project" {
activate_apis = [
"iam.googleapis.com",
- "cloudresourcemanager.googleapis.com"
+ "cloudresourcemanager.googleapis.com",
+ "storage.googleapis.com"
]
# Metadata
@@ -58,5 +61,3 @@ module "base_shared_vpc_project" {
secondary_contact = "example2@example.com"
business_code = var.business_code
}
-
-
diff --git a/4-projects/modules/base_env/example_floating_project.tf b/4-projects/modules/base_env/example_floating_project.tf
index d3188c7af..e8bbe7406 100644
--- a/4-projects/modules/base_env/example_floating_project.tf
+++ b/4-projects/modules/base_env/example_floating_project.tf
@@ -24,6 +24,8 @@ module "floating_project" {
project_budget = var.project_budget
project_prefix = local.project_prefix
+ project_deletion_policy = var.project_deletion_policy
+
# Metadata
project_suffix = "sample-floating"
application_name = "${var.business_code}-sample-application"
diff --git a/4-projects/modules/base_env/example_peering_project.tf b/4-projects/modules/base_env/example_peering_project.tf
index e0e387abf..862836007 100644
--- a/4-projects/modules/base_env/example_peering_project.tf
+++ b/4-projects/modules/base_env/example_peering_project.tf
@@ -40,6 +40,8 @@ module "peering_project" {
project_budget = var.project_budget
project_prefix = local.project_prefix
+ project_deletion_policy = var.project_deletion_policy
+
// Enabling Cloud Build Deploy to use Service Accounts during the build and give permissions to the SA.
// The permissions will be the ones necessary for the deployment of the step 5-app-infra
enable_cloudbuild_deploy = local.enable_cloudbuild_deploy
diff --git a/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf b/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf
index 252d4ec70..5244a53b7 100644
--- a/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf
+++ b/4-projects/modules/base_env/example_restricted_shared_vpc_project.tf
@@ -27,6 +27,7 @@ module "restricted_shared_vpc_project" {
project_budget = var.project_budget
project_prefix = local.project_prefix
+ project_deletion_policy = var.project_deletion_policy
activate_apis = ["accesscontextmanager.googleapis.com"]
vpc_service_control_attach_enabled = local.enforce_vpcsc ? "true" : "false"
diff --git a/4-projects/modules/base_env/example_storage_cmek.tf b/4-projects/modules/base_env/example_storage_cmek.tf
index cd10c2a38..f9a77c08b 100644
--- a/4-projects/modules/base_env/example_storage_cmek.tf
+++ b/4-projects/modules/base_env/example_storage_cmek.tf
@@ -20,7 +20,7 @@ data "google_storage_project_service_account" "gcs_account" {
module "kms" {
source = "terraform-google-modules/kms/google"
- version = "~> 2.1"
+ version = "~> 3.2"
project_id = local.kms_project_id
keyring = var.keyring_name
@@ -44,7 +44,7 @@ resource "random_string" "bucket_name" {
module "gcs_buckets" {
source = "terraform-google-modules/cloud-storage/google//modules/simple_bucket"
- version = "~> 6.0.0"
+ version = "~> 8.0"
project_id = module.base_shared_vpc_project.project_id
location = var.location_gcs
diff --git a/4-projects/modules/base_env/variables.tf b/4-projects/modules/base_env/variables.tf
index 384d35d05..a734b678e 100644
--- a/4-projects/modules/base_env/variables.tf
+++ b/4-projects/modules/base_env/variables.tf
@@ -180,3 +180,15 @@ variable "vpc_service_control_attach_dry_run" {
type = bool
default = false
}
+
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
+
+variable "folder_deletion_protection" {
+ description = "Prevent Terraform from destroying or recreating the folder."
+ type = string
+ default = true
+}
diff --git a/4-projects/modules/infra_pipelines/main.tf b/4-projects/modules/infra_pipelines/main.tf
index 036ff505e..123b5514b 100644
--- a/4-projects/modules/infra_pipelines/main.tf
+++ b/4-projects/modules/infra_pipelines/main.tf
@@ -54,12 +54,14 @@ resource "google_storage_bucket" "cloudbuild_bucket" {
}
module "tf_workspace" {
- source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace"
- version = "~> 8.0"
+ source = "terraform-google-modules/bootstrap/google//modules/tf_cloudbuild_workspace"
+ version = "~> 9.0"
+
for_each = toset(var.app_infra_repos)
- project_id = var.cloudbuild_project_id
- location = var.default_region
+ project_id = var.cloudbuild_project_id
+ location = var.default_region
+ trigger_location = var.default_region
# using bucket custom names for compliance with bucket naming conventions
create_state_bucket = true
@@ -76,6 +78,8 @@ module "tf_workspace" {
diff_sa_project = true
buckets_force_destroy = true
+
+
substitutions = {
"_BILLING_ID" = var.billing_account
"_GAR_REGION" = local.gar_region
diff --git a/4-projects/modules/single_project/README.md b/4-projects/modules/single_project/README.md
index b92f4b388..80758abb9 100644
--- a/4-projects/modules/single_project/README.md
+++ b/4-projects/modules/single_project/README.md
@@ -15,6 +15,7 @@
| org\_id | The organization id for the associated services | `string` | n/a | yes |
| primary\_contact | The primary email contact for the project | `string` | n/a | yes |
| project\_budget | Budget configuration.object({
budget_amount = optional(number, 1000)
alert_spent_percents = optional(list(number), [1.2])
alert_pubsub_topic = optional(string, null)
alert_spend_basis = optional(string, "FORECASTED_SPEND")
}) | `{}` | no |
+| project\_deletion\_policy | The deletion policy for the project created. | `string` | `"PREVENT"` | no |
| project\_prefix | Name prefix to use for projects created. | `string` | `"prj"` | no |
| project\_suffix | The name of the GCP project. Max 16 characters with 3 character business unit code. | `string` | n/a | yes |
| sa\_roles | A list of roles to give the Service Account from App Infra Pipeline. | `map(list(string))` | `{}` | no |
diff --git a/4-projects/modules/single_project/main.tf b/4-projects/modules/single_project/main.tf
index 529eb24a9..eda1b55f5 100644
--- a/4-projects/modules/single_project/main.tf
+++ b/4-projects/modules/single_project/main.tf
@@ -46,7 +46,7 @@ locals {
module "project" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
random_project_id = true
random_project_id_length = 4
@@ -55,6 +55,7 @@ module "project" {
org_id = var.org_id
billing_account = var.billing_account
folder_id = var.folder_id
+ deletion_policy = var.project_deletion_policy
svpc_host_project_id = var.shared_vpc_host_project_id
shared_vpc_subnets = var.shared_vpc_subnets # Optional: To enable subnetting, replace to "module.networking_project.subnetwork_self_link"
diff --git a/4-projects/modules/single_project/variables.tf b/4-projects/modules/single_project/variables.tf
index 429f6d08f..00d68d1de 100644
--- a/4-projects/modules/single_project/variables.tf
+++ b/4-projects/modules/single_project/variables.tf
@@ -160,3 +160,9 @@ variable "enable_cloudbuild_deploy" {
type = bool
default = false
}
+
+variable "project_deletion_policy" {
+ description = "The deletion policy for the project created."
+ type = string
+ default = "PREVENT"
+}
diff --git a/5-app-infra/business_unit_1/development/versions.tf b/5-app-infra/business_unit_1/development/versions.tf
index baa38abbc..bbf8d82ce 100644
--- a/5-app-infra/business_unit_1/development/versions.tf
+++ b/5-app-infra/business_unit_1/development/versions.tf
@@ -21,12 +21,12 @@ terraform {
google = {
source = "hashicorp/google"
- version = ">= 3.77, < 6"
+ version = ">= 3.77, < 7"
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 3.77, < 6"
+ version = ">= 3.77, < 7"
}
null = {
diff --git a/5-app-infra/business_unit_1/nonproduction/versions.tf b/5-app-infra/business_unit_1/nonproduction/versions.tf
index baa38abbc..bbf8d82ce 100644
--- a/5-app-infra/business_unit_1/nonproduction/versions.tf
+++ b/5-app-infra/business_unit_1/nonproduction/versions.tf
@@ -21,12 +21,12 @@ terraform {
google = {
source = "hashicorp/google"
- version = ">= 3.77, < 6"
+ version = ">= 3.77, < 7"
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 3.77, < 6"
+ version = ">= 3.77, < 7"
}
null = {
diff --git a/5-app-infra/business_unit_1/production/versions.tf b/5-app-infra/business_unit_1/production/versions.tf
index baa38abbc..bbf8d82ce 100644
--- a/5-app-infra/business_unit_1/production/versions.tf
+++ b/5-app-infra/business_unit_1/production/versions.tf
@@ -21,12 +21,12 @@ terraform {
google = {
source = "hashicorp/google"
- version = ">= 3.77, < 6"
+ version = ">= 3.77, < 7"
}
google-beta = {
source = "hashicorp/google-beta"
- version = ">= 3.77, < 6"
+ version = ">= 3.77, < 7"
}
null = {
diff --git a/5-app-infra/modules/env_base/main.tf b/5-app-infra/modules/env_base/main.tf
index 6d7821183..078743720 100644
--- a/5-app-infra/modules/env_base/main.tf
+++ b/5-app-infra/modules/env_base/main.tf
@@ -39,6 +39,7 @@ locals {
env_project_id = local.env_project_ids[var.project_suffix]
subnetwork_self_link = local.env_project_subnets[var.project_suffix]
+ subnetwork_project = element(split("/", local.subnetwork_self_link), index(split("/", local.subnetwork_self_link), "projects") + 1, )
resource_manager_tags = local.env_project_resource_manager_tags[var.project_suffix]
}
@@ -61,7 +62,7 @@ resource "google_service_account" "compute_engine_service_account" {
module "instance_template" {
source = "terraform-google-modules/vm/google//modules/instance_template"
- version = "~> 11.0"
+ version = "~> 12.0"
machine_type = var.machine_type
region = var.region
@@ -80,10 +81,11 @@ module "instance_template" {
module "compute_instance" {
source = "terraform-google-modules/vm/google//modules/compute_instance"
- version = "~> 11.0"
+ version = "~> 12.0"
region = var.region
subnetwork = local.subnetwork_self_link
+ subnetwork_project = local.subnetwork_project
num_instances = var.num_instances
hostname = var.hostname
instance_template = module.instance_template.self_link
diff --git a/helpers/foundation-deployer/global.tfvars.example b/helpers/foundation-deployer/global.tfvars.example
index 1a0f17946..b9ab862de 100644
--- a/helpers/foundation-deployer/global.tfvars.example
+++ b/helpers/foundation-deployer/global.tfvars.example
@@ -27,6 +27,8 @@ foundation_code_path = "FULL_PATH_TO_FOLDER_WHERE_THE_EXAMPLE_FOUNDATION_CODE_WA
// See https://cloud.google.com/sdk/gcloud/reference/config/set#EXAMPLES
validator_project_id = "EXISTING_PROJECT_ID"
+project_deletion_policy = "DELETE"
+folder_deletion_protection = false
// 0-bootstrap inputs
// https://github.com/terraform-google-modules/terraform-example-foundation/blob/master/0-bootstrap/README.md#inputs
diff --git a/helpers/foundation-deployer/stages/apply.go b/helpers/foundation-deployer/stages/apply.go
index 2c1afb415..d48083083 100644
--- a/helpers/foundation-deployer/stages/apply.go
+++ b/helpers/foundation-deployer/stages/apply.go
@@ -45,6 +45,8 @@ func DeployBootstrapStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, c Co
BucketTfstateKmsForceDestroy: tfvars.BucketTfstateKmsForceDestroy,
Groups: tfvars.Groups,
InitialGroupConfig: tfvars.InitialGroupConfig,
+ FolderDeletionProtection: tfvars.FolderDeletionProtection,
+ ProjectDeletionPolicy: tfvars.ProjectDeletionPolicy,
}
err := utils.WriteTfvars(filepath.Join(c.FoundationPath, BootstrapStep, "terraform.tfvars"), bootstrapTfvars)
@@ -205,6 +207,8 @@ func DeployOrgStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, outputs Bo
LogExportStorageForceDestroy: tfvars.LogExportStorageForceDestroy,
LogExportStorageLocation: tfvars.LogExportStorageLocation,
BillingExportDatasetLocation: tfvars.BillingExportDatasetLocation,
+ FolderDeletionProtection: tfvars.FolderDeletionProtection,
+ ProjectDeletionPolicy: tfvars.ProjectDeletionPolicy,
}
orgTfvars.GcpGroups = GcpGroups{}
if tfvars.HasOptionalGroupsCreation() {
@@ -247,7 +251,9 @@ func DeployOrgStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, outputs Bo
func DeployEnvStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, outputs BootstrapOutputs, c CommonConf) error {
envsTfvars := EnvsTfvars{
- RemoteStateBucket: outputs.RemoteStateBucket,
+ RemoteStateBucket: outputs.RemoteStateBucket,
+ FolderDeletionProtection: tfvars.FolderDeletionProtection,
+ ProjectDeletionPolicy: tfvars.ProjectDeletionPolicy,
}
err := utils.WriteTfvars(filepath.Join(c.FoundationPath, EnvironmentsStep, "terraform.tfvars"), envsTfvars)
if err != nil {
@@ -338,8 +344,10 @@ func DeployProjectsStage(t testing.TB, s steps.Steps, tfvars GlobalTFVars, outpu
}
//for each environment
envTfvars := ProjEnvTfvars{
- LocationKMS: tfvars.LocationKMS,
- LocationGCS: tfvars.LocationGCS,
+ LocationKMS: tfvars.LocationKMS,
+ LocationGCS: tfvars.LocationGCS,
+ FolderDeletionProtection: tfvars.FolderDeletionProtection,
+ ProjectDeletionPolicy: tfvars.ProjectDeletionPolicy,
}
for _, envfile := range []string{
"development.auto.tfvars",
diff --git a/helpers/foundation-deployer/stages/data.go b/helpers/foundation-deployer/stages/data.go
index 89db39c2d..a3b64687c 100644
--- a/helpers/foundation-deployer/stages/data.go
+++ b/helpers/foundation-deployer/stages/data.go
@@ -159,6 +159,8 @@ type GlobalTFVars struct {
ValidatorProjectId *string `hcl:"validator_project_id"`
Groups Groups `hcl:"groups"`
InitialGroupConfig *string `hcl:"initial_group_config"`
+ FolderDeletionProtection bool `hcl:"folder_deletion_protection"`
+ ProjectDeletionPolicy string `hcl:"project_deletion_policy"`
}
// HasValidatorProj checks if a Validator Project was provided
@@ -205,6 +207,8 @@ type BootstrapTfvars struct {
BucketTfstateKmsForceDestroy *bool `hcl:"bucket_tfstate_kms_force_destroy"`
Groups Groups `hcl:"groups"`
InitialGroupConfig *string `hcl:"initial_group_config"`
+ FolderDeletionProtection bool `hcl:"folder_deletion_protection"`
+ ProjectDeletionPolicy string `hcl:"project_deletion_policy"`
}
type OrgTfvars struct {
@@ -220,10 +224,14 @@ type OrgTfvars struct {
LogExportStorageLocation string `hcl:"log_export_storage_location"`
BillingExportDatasetLocation string `hcl:"billing_export_dataset_location"`
GcpGroups GcpGroups `hcl:"gcp_groups"`
+ FolderDeletionProtection bool `hcl:"folder_deletion_protection"`
+ ProjectDeletionPolicy string `hcl:"project_deletion_policy"`
}
type EnvsTfvars struct {
- RemoteStateBucket string `hcl:"remote_state_bucket"`
+ RemoteStateBucket string `hcl:"remote_state_bucket"`
+ FolderDeletionProtection bool `hcl:"folder_deletion_protection"`
+ ProjectDeletionPolicy string `hcl:"project_deletion_policy"`
}
type NetCommonTfvars struct {
@@ -250,8 +258,10 @@ type ProjSharedTfvars struct {
}
type ProjEnvTfvars struct {
- LocationKMS string `hcl:"location_kms"`
- LocationGCS string `hcl:"location_gcs"`
+ LocationKMS string `hcl:"location_kms"`
+ LocationGCS string `hcl:"location_gcs"`
+ FolderDeletionProtection bool `hcl:"folder_deletion_protection"`
+ ProjectDeletionPolicy string `hcl:"project_deletion_policy"`
}
type AppInfraCommonTfvars struct {
diff --git a/test/integration/bootstrap/bootstrap_test.go b/test/integration/bootstrap/bootstrap_test.go
index 41e46466b..aef67be44 100644
--- a/test/integration/bootstrap/bootstrap_test.go
+++ b/test/integration/bootstrap/bootstrap_test.go
@@ -49,6 +49,8 @@ func TestBootstrap(t *testing.T) {
vars := map[string]interface{}{
"bucket_force_destroy": true,
"bucket_tfstate_kms_force_destroy": true,
+ "folder_deletion_protection": false,
+ "project_deletion_policy": "DELETE",
}
temp := tft.NewTFBlueprintTest(t,
diff --git a/test/integration/envs/envs_test.go b/test/integration/envs/envs_test.go
index ed06d1786..15de28f31 100644
--- a/test/integration/envs/envs_test.go
+++ b/test/integration/envs/envs_test.go
@@ -40,7 +40,9 @@ func TestEnvs(t *testing.T) {
backend_bucket := bootstrap.GetStringOutput("gcs_bucket_tfstate")
vars := map[string]interface{}{
- "remote_state_bucket": backend_bucket,
+ "remote_state_bucket": backend_bucket,
+ "folder_deletion_protection": false,
+ "project_deletion_policy": "DELETE",
}
backendConfig := map[string]interface{}{
diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go
index 00c6b7b85..8b4b942cc 100644
--- a/test/integration/org/org_test.go
+++ b/test/integration/org/org_test.go
@@ -41,6 +41,8 @@ func TestOrg(t *testing.T) {
vars := map[string]interface{}{
"remote_state_bucket": backend_bucket,
"log_export_storage_force_destroy": "true",
+ "folder_deletion_protection": false,
+ "project_deletion_policy": "DELETE",
}
backendConfig := map[string]interface{}{
diff --git a/test/integration/projects/projects_test.go b/test/integration/projects/projects_test.go
index 27cb910be..f630045d5 100644
--- a/test/integration/projects/projects_test.go
+++ b/test/integration/projects/projects_test.go
@@ -128,7 +128,9 @@ func TestProjects(t *testing.T) {
sharedCloudBuildSA := terraform.OutputMap(t, shared.GetTFOptions(), "terraform_service_accounts")[tt.repo]
vars := map[string]interface{}{
- "remote_state_bucket": backend_bucket,
+ "remote_state_bucket": backend_bucket,
+ "folder_deletion_protection": false,
+ "project_deletion_policy": "DELETE",
}
projects := tft.NewTFBlueprintTest(t,
diff --git a/test/setup/main.tf b/test/setup/main.tf
index 7b85df91d..976fba60b 100644
--- a/test/setup/main.tf
+++ b/test/setup/main.tf
@@ -40,13 +40,14 @@ resource "random_string" "two_alphanumeric" {
}
resource "google_folder" "test_folder" {
- display_name = "test_foundation_folder_${random_string.suffix.result}"
- parent = "folders/${var.folder_id}"
+ display_name = "test_foundation_folder_${random_string.suffix.result}"
+ parent = "folders/${var.folder_id}"
+ deletion_protection = false
}
module "project" {
source = "terraform-google-modules/project-factory/google"
- version = "~> 15.0"
+ version = "~> 17.0"
name = "ci-foundation-${random_string.suffix.result}"
random_project_id = true
@@ -54,6 +55,7 @@ module "project" {
org_id = var.org_id
folder_id = var.folder_id
billing_account = var.billing_account
+ deletion_policy = "DELETE"
activate_apis = [
"cloudresourcemanager.googleapis.com",
diff --git a/test/setup/outputs.tf b/test/setup/outputs.tf
index bff0125e8..121f8560e 100644
--- a/test/setup/outputs.tf
+++ b/test/setup/outputs.tf
@@ -109,3 +109,14 @@ output "create_unique_tag_key" {
description = "Set to true to avoid tag key name colision during integrated tests. Tag keys are organization-wide unique names."
value = true
}
+
+output "project_deletion_policy" {
+ description = "The deletion policy for the project created. Set to `DELETE` during integrated tests so that projects can be destroyed."
+ value = "DELETE"
+}
+
+variable "folder_deletion_protection" {
+ description = "Prevent Terraform from destroying or recreating the folder. Set to `false` during integrated tests so that folders can be destroyed."
+ type = bool
+ default = false
+}