diff --git a/0-bootstrap/README.md b/0-bootstrap/README.md index dd93e13b7..a9941e367 100644 --- a/0-bootstrap/README.md +++ b/0-bootstrap/README.md @@ -361,6 +361,7 @@ 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 | diff --git a/0-bootstrap/main.tf b/0-bootstrap/main.tf index 03a500605..1063e58fe 100644 --- a/0-bootstrap/main.tf +++ b/0-bootstrap/main.tf @@ -35,8 +35,9 @@ 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" { diff --git a/0-bootstrap/variables.tf b/0-bootstrap/variables.tf index ee20bba69..db7e27c65 100644 --- a/0-bootstrap/variables.tf +++ b/0-bootstrap/variables.tf @@ -96,6 +96,12 @@ variable "project_deletion_policy" { 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/1-org/envs/shared/README.md b/1-org/envs/shared/README.md index 8fe1ace97..e12dc5bcf 100644 --- a/1-org/envs/shared/README.md +++ b/1-org/envs/shared/README.md @@ -12,6 +12,7 @@ | 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.
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` | `null` | no | diff --git a/1-org/envs/shared/folders.tf b/1-org/envs/shared/folders.tf index eff64af4e..484589573 100644 --- a/1-org/envs/shared/folders.tf +++ b/1-org/envs/shared/folders.tf @@ -19,11 +19,13 @@ *****************************************/ resource "google_folder" "common" { - display_name = "${local.folder_prefix}-common" - parent = local.parent + display_name = "${local.folder_prefix}-common" + parent = local.parent + deletion_protection = var.folder_deletion_protection } resource "google_folder" "network" { - display_name = "${local.folder_prefix}-network" - parent = local.parent + display_name = "${local.folder_prefix}-network" + parent = local.parent + deletion_protection = var.folder_deletion_protection } diff --git a/1-org/envs/shared/variables.tf b/1-org/envs/shared/variables.tf index 7c261c109..b39073d7d 100644 --- a/1-org/envs/shared/variables.tf +++ b/1-org/envs/shared/variables.tf @@ -199,3 +199,9 @@ variable "project_deletion_policy" { type = string default = "PREVENT" } + +variable "folder_deletion_protection" { + description = "Prevent Terraform from destroying or recreating the folder." + type = string + default = true +} diff --git a/2-environments/envs/development/README.md b/2-environments/envs/development/README.md index cf01bc7f7..883e0f0bc 100644 --- a/2-environments/envs/development/README.md +++ b/2-environments/envs/development/README.md @@ -3,6 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | 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/2-environments/envs/development/main.tf b/2-environments/envs/development/main.tf index 2f66c50dc..3be567bae 100644 --- a/2-environments/envs/development/main.tf +++ b/2-environments/envs/development/main.tf @@ -22,5 +22,6 @@ module "env" { remote_state_bucket = var.remote_state_bucket tfc_org_name = var.tfc_org_name - project_deletion_policy = var.project_deletion_policy + project_deletion_policy = var.project_deletion_policy + folder_deletion_protection = var.folder_deletion_protection } diff --git a/2-environments/envs/development/variables.tf b/2-environments/envs/development/variables.tf index db3da85da..d2ab8ccc1 100644 --- a/2-environments/envs/development/variables.tf +++ b/2-environments/envs/development/variables.tf @@ -30,3 +30,9 @@ variable "project_deletion_policy" { type = string default = "PREVENT" } + +variable "folder_deletion_protection" { + description = "Prevent Terraform from destroying or recreating the folder." + type = string + default = true +} diff --git a/2-environments/envs/nonproduction/README.md b/2-environments/envs/nonproduction/README.md index cf01bc7f7..883e0f0bc 100644 --- a/2-environments/envs/nonproduction/README.md +++ b/2-environments/envs/nonproduction/README.md @@ -3,6 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | 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/2-environments/envs/nonproduction/main.tf b/2-environments/envs/nonproduction/main.tf index 350e72ec0..74efd1376 100644 --- a/2-environments/envs/nonproduction/main.tf +++ b/2-environments/envs/nonproduction/main.tf @@ -22,5 +22,6 @@ module "env" { remote_state_bucket = var.remote_state_bucket tfc_org_name = var.tfc_org_name - project_deletion_policy = var.project_deletion_policy + project_deletion_policy = var.project_deletion_policy + folder_deletion_protection = var.folder_deletion_protection } diff --git a/2-environments/envs/nonproduction/variables.tf b/2-environments/envs/nonproduction/variables.tf index db3da85da..d2ab8ccc1 100644 --- a/2-environments/envs/nonproduction/variables.tf +++ b/2-environments/envs/nonproduction/variables.tf @@ -30,3 +30,9 @@ variable "project_deletion_policy" { type = string default = "PREVENT" } + +variable "folder_deletion_protection" { + description = "Prevent Terraform from destroying or recreating the folder." + type = string + default = true +} diff --git a/2-environments/envs/production/README.md b/2-environments/envs/production/README.md index 19cb9a2f1..ba77099ab 100644 --- a/2-environments/envs/production/README.md +++ b/2-environments/envs/production/README.md @@ -3,6 +3,7 @@ | Name | Description | Type | Default | Required | |------|-------------|------|---------|:--------:| +| folder\_deletion\_protection | Prevent Terraform from destroying or recreating the folder. | `string` | `true` | 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/2-environments/envs/production/main.tf b/2-environments/envs/production/main.tf index deba01685..4f4845146 100644 --- a/2-environments/envs/production/main.tf +++ b/2-environments/envs/production/main.tf @@ -22,7 +22,8 @@ module "env" { remote_state_bucket = var.remote_state_bucket tfc_org_name = var.tfc_org_name - project_deletion_policy = var.project_deletion_policy + project_deletion_policy = var.project_deletion_policy + folder_deletion_protection = var.folder_deletion_protection assured_workload_configuration = { enabled = false diff --git a/2-environments/envs/production/variables.tf b/2-environments/envs/production/variables.tf index 1cb41ac55..d2ab8ccc1 100644 --- a/2-environments/envs/production/variables.tf +++ b/2-environments/envs/production/variables.tf @@ -31,3 +31,8 @@ variable "project_deletion_policy" { default = "PREVENT" } +variable "folder_deletion_protection" { + description = "Prevent Terraform from destroying or recreating the folder." + type = string + default = true +} diff --git a/2-environments/modules/env_baseline/README.md b/2-environments/modules/env_baseline/README.md index de489bdbc..4a35926e3 100644 --- a/2-environments/modules/env_baseline/README.md +++ b/2-environments/modules/env_baseline/README.md @@ -6,6 +6,7 @@ | assured\_workload\_configuration | Assured Workload configuration. See https://cloud.google.com/assured-workloads ."
enabled: If the assured workload should be created.
location: The location where the workload will be created.
display\_name: User-assigned resource display name.
compliance\_regime: Supported Compliance Regimes. See https://cloud.google.com/assured-workloads/docs/reference/rest/Shared.Types/ComplianceRegime .
resource\_type: The type of resource. One of CONSUMER\_FOLDER, KEYRING, or ENCRYPTION\_KEYS\_PROJECT. |
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.
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({
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 | 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/variables.tf b/2-environments/modules/env_baseline/variables.tf index 6aa14afc4..81ab12a83 100644 --- a/2-environments/modules/env_baseline/variables.tf +++ b/2-environments/modules/env_baseline/variables.tf @@ -87,3 +87,9 @@ variable "project_deletion_policy" { 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/development/README.md b/4-projects/business_unit_1/development/README.md index 25eaa0408..9d723d711 100644 --- a/4-projects/business_unit_1/development/README.md +++ b/4-projects/business_unit_1/development/README.md @@ -3,6 +3,7 @@ | 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 | diff --git a/4-projects/business_unit_1/development/main.tf b/4-projects/business_unit_1/development/main.tf index edc631b99..1ad8a4131 100644 --- a/4-projects/business_unit_1/development/main.tf +++ b/4-projects/business_unit_1/development/main.tf @@ -35,4 +35,5 @@ module "env" { 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 435a765cc..7add57dfc 100644 --- a/4-projects/business_unit_1/development/variables.tf +++ b/4-projects/business_unit_1/development/variables.tf @@ -62,3 +62,9 @@ variable "project_deletion_policy" { 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 25eaa0408..9d723d711 100644 --- a/4-projects/business_unit_1/nonproduction/README.md +++ b/4-projects/business_unit_1/nonproduction/README.md @@ -3,6 +3,7 @@ | 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 | diff --git a/4-projects/business_unit_1/nonproduction/main.tf b/4-projects/business_unit_1/nonproduction/main.tf index f39ee8313..b8a4514b7 100644 --- a/4-projects/business_unit_1/nonproduction/main.tf +++ b/4-projects/business_unit_1/nonproduction/main.tf @@ -35,4 +35,5 @@ module "env" { 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 435a765cc..7add57dfc 100644 --- a/4-projects/business_unit_1/nonproduction/variables.tf +++ b/4-projects/business_unit_1/nonproduction/variables.tf @@ -62,3 +62,9 @@ variable "project_deletion_policy" { 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 25eaa0408..9d723d711 100644 --- a/4-projects/business_unit_1/production/README.md +++ b/4-projects/business_unit_1/production/README.md @@ -3,6 +3,7 @@ | 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 | diff --git a/4-projects/business_unit_1/production/main.tf b/4-projects/business_unit_1/production/main.tf index a60881e93..4bf4b9f74 100644 --- a/4-projects/business_unit_1/production/main.tf +++ b/4-projects/business_unit_1/production/main.tf @@ -35,4 +35,5 @@ module "env" { 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 435a765cc..7add57dfc 100644 --- a/4-projects/business_unit_1/production/variables.tf +++ b/4-projects/business_unit_1/production/variables.tf @@ -62,3 +62,9 @@ variable "project_deletion_policy" { 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/base_env/README.md b/4-projects/modules/base_env/README.md index b64447262..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 | 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/variables.tf b/4-projects/modules/base_env/variables.tf index e8ee1845b..a734b678e 100644 --- a/4-projects/modules/base_env/variables.tf +++ b/4-projects/modules/base_env/variables.tf @@ -186,3 +186,9 @@ variable "project_deletion_policy" { type = string default = "PREVENT" } + +variable "folder_deletion_protection" { + description = "Prevent Terraform from destroying or recreating the folder." + type = string + default = true +} diff --git a/helpers/foundation-deployer/global.tfvars.example b/helpers/foundation-deployer/global.tfvars.example index 0347e625e..f86186d01 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 90b6a9537..0e9d26648 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{ - ProjectsKMSLocation: tfvars.ProjectsKMSLocation, - ProjectsGCSLocation: tfvars.ProjectsGCSLocation, + ProjectsKMSLocation: tfvars.ProjectsKMSLocation, + ProjectsGCSLocation: tfvars.ProjectsGCSLocation, + 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 6a40fed9f..d1289aa46 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 { - ProjectsKMSLocation string `hcl:"projects_kms_location"` - ProjectsGCSLocation string `hcl:"projects_gcs_location"` + ProjectsKMSLocation string `hcl:"projects_kms_location"` + ProjectsGCSLocation string `hcl:"projects_gcs_location"` + FolderDeletionProtection bool `hcl:"folder_deletion_protection"` + ProjectDeletionPolicy string `hcl:"project_deletion_policy"` } type AppInfraCommonTfvars struct { diff --git a/test/setup/main.tf b/test/setup/main.tf index cb8cdfd9d..976fba60b 100644 --- a/test/setup/main.tf +++ b/test/setup/main.tf @@ -40,8 +40,9 @@ 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" { diff --git a/test/setup/outputs.tf b/test/setup/outputs.tf index 4b19fdbc2..59df276d9 100644 --- a/test/setup/outputs.tf +++ b/test/setup/outputs.tf @@ -114,3 +114,9 @@ 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 = string + default = false +}