diff --git a/0-bootstrap/cb.tf b/0-bootstrap/cb.tf index ef7e922b4..50f11636f 100644 --- a/0-bootstrap/cb.tf +++ b/0-bootstrap/cb.tf @@ -133,7 +133,7 @@ module "tf_source" { } # Remove after github.com/terraform-google-modules/terraform-google-bootstrap/issues/160 - depends_on = [module.seed_bootstrap] + depends_on = [module.seed_bootstrap, time_sleep.wait_organization_policies] } resource "google_project_service_identity" "workflows_identity" { diff --git a/0-bootstrap/main.tf b/0-bootstrap/main.tf index 1063e58fe..a115eca61 100644 --- a/0-bootstrap/main.tf +++ b/0-bootstrap/main.tf @@ -101,6 +101,5 @@ module "seed_bootstrap" { sa_org_iam_permissions = [] - depends_on = [module.required_group] + depends_on = [module.required_group, time_sleep.wait_organization_policies] } - diff --git a/0-bootstrap/org_policy.tf b/0-bootstrap/org_policy.tf new file mode 100644 index 000000000..be569af22 --- /dev/null +++ b/0-bootstrap/org_policy.tf @@ -0,0 +1,45 @@ +/** + * Copyright 2024 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 { + organization_id = var.parent_folder != "" ? null : var.org_id + folder_id = var.parent_folder != "" ? var.parent_folder : null + policy_for = var.parent_folder != "" ? "folder" : "organization" + + boolean_type_organization_policies = toset([ + "compute.skipDefaultNetworkCreation" + ]) +} + +module "organization_policies_type_boolean" { + source = "terraform-google-modules/org-policy/google" + version = "~> 5.1" + for_each = local.boolean_type_organization_policies + + organization_id = local.organization_id + folder_id = local.folder_id + policy_for = local.policy_for + policy_type = "boolean" + enforce = "true" + constraint = "constraints/${each.value}" +} + +resource "time_sleep" "wait_organization_policies" { + create_duration = "60s" + depends_on = [ + module.organization_policies_type_boolean + ] +} diff --git a/1-org/envs/shared/org_policy.tf b/1-org/envs/shared/org_policy.tf index 5c43dbbc1..b49e69f71 100644 --- a/1-org/envs/shared/org_policy.tf +++ b/1-org/envs/shared/org_policy.tf @@ -27,7 +27,6 @@ locals { boolean_type_organization_policies = toset([ "compute.disableNestedVirtualization", "compute.disableSerialPortAccess", - "compute.skipDefaultNetworkCreation", "compute.restrictXpnProjectLienRemoval", "compute.disableVpcExternalIpv6", "compute.setNewProjectDefaultToZonalDNSOnly", diff --git a/1-org/envs/shared/projects.tf b/1-org/envs/shared/projects.tf index 2cf27b963..e54236e8f 100644 --- a/1-org/envs/shared/projects.tf +++ b/1-org/envs/shared/projects.tf @@ -45,6 +45,7 @@ module "org_audit_logs" { folder_id = google_folder.common.id deletion_policy = var.project_deletion_policy activate_apis = ["logging.googleapis.com", "bigquery.googleapis.com", "billingbudgets.googleapis.com"] + auto_create_network = true labels = { environment = "common" @@ -79,6 +80,7 @@ module "org_billing_export" { folder_id = google_folder.common.id deletion_policy = var.project_deletion_policy activate_apis = ["logging.googleapis.com", "bigquery.googleapis.com", "billingbudgets.googleapis.com"] + auto_create_network = true labels = { environment = "common" @@ -113,6 +115,8 @@ module "common_kms" { folder_id = google_folder.common.id deletion_policy = var.project_deletion_policy activate_apis = ["logging.googleapis.com", "cloudkms.googleapis.com", "billingbudgets.googleapis.com"] + auto_create_network = true + labels = { environment = "common" @@ -148,6 +152,8 @@ module "org_secrets" { folder_id = google_folder.common.id deletion_policy = var.project_deletion_policy activate_apis = ["logging.googleapis.com", "secretmanager.googleapis.com", "billingbudgets.googleapis.com"] + auto_create_network = true + labels = { environment = "common" @@ -182,6 +188,8 @@ module "interconnect" { folder_id = google_folder.network.id deletion_policy = var.project_deletion_policy activate_apis = ["billingbudgets.googleapis.com", "compute.googleapis.com"] + auto_create_network = true + labels = { environment = "network" @@ -216,6 +224,8 @@ module "scc_notifications" { folder_id = google_folder.common.id deletion_policy = var.project_deletion_policy activate_apis = ["logging.googleapis.com", "pubsub.googleapis.com", "securitycenter.googleapis.com", "billingbudgets.googleapis.com", "cloudkms.googleapis.com"] + auto_create_network = true + labels = { environment = "common" @@ -249,6 +259,8 @@ module "dns_hub" { billing_account = local.billing_account folder_id = google_folder.network.id deletion_policy = var.project_deletion_policy + auto_create_network = true + activate_apis = [ "compute.googleapis.com", @@ -292,6 +304,8 @@ module "base_network_hub" { billing_account = local.billing_account folder_id = google_folder.network.id deletion_policy = var.project_deletion_policy + auto_create_network = true + activate_apis = [ "compute.googleapis.com", @@ -343,6 +357,8 @@ module "restricted_network_hub" { billing_account = local.billing_account folder_id = google_folder.network.id deletion_policy = var.project_deletion_policy + auto_create_network = true + activate_apis = [ "compute.googleapis.com", diff --git a/1-org/modules/network/main.tf b/1-org/modules/network/main.tf index d1b22bd52..bf33e93a2 100644 --- a/1-org/modules/network/main.tf +++ b/1-org/modules/network/main.tf @@ -30,6 +30,7 @@ module "base_shared_vpc_host_project" { folder_id = var.folder_id disable_services_on_destroy = false deletion_policy = var.project_deletion_policy + auto_create_network = true activate_apis = [ "compute.googleapis.com", @@ -67,6 +68,7 @@ module "restricted_shared_vpc_host_project" { folder_id = var.folder_id disable_services_on_destroy = false deletion_policy = var.project_deletion_policy + auto_create_network = true activate_apis = [ "compute.googleapis.com", diff --git a/2-environments/modules/env_baseline/kms.tf b/2-environments/modules/env_baseline/kms.tf index 01dc42f26..d3b9ea4ab 100644 --- a/2-environments/modules/env_baseline/kms.tf +++ b/2-environments/modules/env_baseline/kms.tf @@ -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"] + auto_create_network = true deletion_policy = var.project_deletion_policy labels = { diff --git a/2-environments/modules/env_baseline/secrets.tf b/2-environments/modules/env_baseline/secrets.tf index 6ff24a4ec..d9c564cd0 100644 --- a/2-environments/modules/env_baseline/secrets.tf +++ b/2-environments/modules/env_baseline/secrets.tf @@ -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"] + auto_create_network = true deletion_policy = var.project_deletion_policy labels = { diff --git a/4-projects/modules/single_project/main.tf b/4-projects/modules/single_project/main.tf index eda1b55f5..97f24e74e 100644 --- a/4-projects/modules/single_project/main.tf +++ b/4-projects/modules/single_project/main.tf @@ -55,6 +55,7 @@ module "project" { org_id = var.org_id billing_account = var.billing_account folder_id = var.folder_id + auto_create_network = true deletion_policy = var.project_deletion_policy svpc_host_project_id = var.shared_vpc_host_project_id diff --git a/test/integration/bootstrap/bootstrap_test.go b/test/integration/bootstrap/bootstrap_test.go index aef67be44..14bfcf571 100644 --- a/test/integration/bootstrap/bootstrap_test.go +++ b/test/integration/bootstrap/bootstrap_test.go @@ -149,6 +149,8 @@ func TestBootstrap(t *testing.T) { bootstrap.DefineVerify( func(assert *assert.Assertions) { + parentFolder := terraform.OutputMap(t, bootstrap.GetTFOptions(), "common_config")["parent_folder"] + // cloud build project cbProjectID := bootstrap.GetStringOutput("cloudbuild_project_id") artifactsBktName := terraform.OutputMap(t, bootstrap.GetTFOptions(), "gcs_bucket_cloudbuild_artifacts") @@ -306,8 +308,17 @@ func TestBootstrap(t *testing.T) { assert.Subset(listRoles, sa.orgRoles, fmt.Sprintf("service account %s should have organization level roles", terraformSAEmail)) } } + // boolean organization policies + for _, booleanConstraint := range []string{ + "constraints/compute.skipDefaultNetworkCreation", + } { + orgPolicy := gcloud.Runf(t, "resource-manager org-policies describe %s --folder %s", booleanConstraint, parentFolder) + assert.True(orgPolicy.Get("booleanPolicy.enforced").Bool(), fmt.Sprintf("org policy %s should be enforced", booleanConstraint)) + } }) + + bootstrap.DefineTeardown(func(assert *assert.Assertions) { // configure options to pull state from GCS bucket cwd, err := os.Getwd() diff --git a/test/integration/org/org_test.go b/test/integration/org/org_test.go index 8b4b942cc..570efe25c 100644 --- a/test/integration/org/org_test.go +++ b/test/integration/org/org_test.go @@ -160,7 +160,6 @@ func TestOrg(t *testing.T) { for _, booleanConstraint := range []string{ "constraints/compute.disableNestedVirtualization", "constraints/compute.disableSerialPortAccess", - "constraints/compute.skipDefaultNetworkCreation", "constraints/compute.restrictXpnProjectLienRemoval", "constraints/sql.restrictPublicIp", "constraints/sql.restrictAuthorizedNetworks", diff --git a/test/setup/main.tf b/test/setup/main.tf index 976fba60b..415f331d6 100644 --- a/test/setup/main.tf +++ b/test/setup/main.tf @@ -56,6 +56,7 @@ module "project" { folder_id = var.folder_id billing_account = var.billing_account deletion_policy = "DELETE" + auto_create_network = true activate_apis = [ "cloudresourcemanager.googleapis.com",