From 3b269bee7bb7aeda53751fb4d3d5b49b8e41fd6a Mon Sep 17 00:00:00 2001 From: Thiago Nache Carvalho Date: Fri, 2 Oct 2020 14:04:32 -0300 Subject: [PATCH] feat: Add `enable_shared_vpc_host_project` to create project as shared VPC host project (#465) --- README.md | 1 + examples/shared_vpc/main.tf | 25 +++++++++++------------ main.tf | 3 ++- modules/core_project_factory/main.tf | 16 ++++++++++----- modules/core_project_factory/outputs.tf | 3 ++- modules/core_project_factory/variables.tf | 10 +++++++-- modules/gsuite_enabled/README.md | 1 + modules/gsuite_enabled/main.tf | 3 ++- modules/gsuite_enabled/variables.tf | 6 ++++++ modules/shared_vpc/main.tf | 2 +- test/fixtures/full/versions.tf | 5 +++++ variables.tf | 6 ++++++ 12 files changed, 57 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index 2d98efa0..9c4d2500 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ determining that location is as follows: | disable\_dependent\_services | Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed. | bool | `"true"` | no | | disable\_services\_on\_destroy | Whether project services will be disabled when the resources are destroyed | string | `"true"` | no | | domain | The domain name (optional). | string | `""` | no | +| enable\_shared\_vpc\_host\_project | If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false. | bool | `"false"` | no | | folder\_id | The ID of a folder to host this project | string | `""` | no | | group\_name | A group to control the project by being assigned group_role (defaults to project editor) | string | `""` | no | | group\_role | The role to give the controlling group (group_name) over the project (defaults to project editor) | string | `"roles/editor"` | no | diff --git a/examples/shared_vpc/main.tf b/examples/shared_vpc/main.tf index f0d96039..5da38f18 100644 --- a/examples/shared_vpc/main.tf +++ b/examples/shared_vpc/main.tf @@ -42,13 +42,14 @@ provider "random" { Host Project Creation *****************************************/ module "host-project" { - source = "../../" - random_project_id = true - name = var.host_project_name - org_id = var.organization_id - folder_id = var.folder_id - billing_account = var.billing_account - skip_gcloud_download = true + source = "../../" + random_project_id = true + name = var.host_project_name + org_id = var.organization_id + folder_id = var.folder_id + billing_account = var.billing_account + skip_gcloud_download = true + enable_shared_vpc_host_project = true } /****************************************** @@ -58,11 +59,9 @@ module "vpc" { source = "terraform-google-modules/network/google" version = "~> 2.1.0" - project_id = module.host-project.project_id - network_name = var.network_name - + project_id = module.host-project.project_id + network_name = var.network_name delete_default_internet_gateway_routes = true - shared_vpc_host = true subnets = [ { @@ -114,7 +113,7 @@ module "service-project" { billing_account = var.billing_account shared_vpc_enabled = true - shared_vpc = module.vpc.project_id + shared_vpc = module.host-project.project_id shared_vpc_subnets = module.vpc.subnets_self_links activate_apis = [ @@ -142,7 +141,7 @@ module "service-project-b" { billing_account = var.billing_account shared_vpc_enabled = true - shared_vpc = module.vpc.project_id + shared_vpc = module.host-project.project_id activate_apis = [ "compute.googleapis.com", diff --git a/main.tf b/main.tf index 8f5c6137..2727ba1a 100644 --- a/main.tf +++ b/main.tf @@ -37,7 +37,8 @@ module "project-factory" { name = var.name project_id = var.project_id shared_vpc = var.shared_vpc - shared_vpc_enabled = var.shared_vpc != "" + enable_shared_vpc_service_project = var.shared_vpc != "" + enable_shared_vpc_host_project = var.enable_shared_vpc_host_project billing_account = var.billing_account folder_id = var.folder_id sa_role = var.sa_role diff --git a/modules/core_project_factory/main.tf b/modules/core_project_factory/main.tf index 24422e43..ee15c2e9 100644 --- a/modules/core_project_factory/main.tf +++ b/modules/core_project_factory/main.tf @@ -127,7 +127,7 @@ module "project_services" { Shared VPC configuration *****************************************/ resource "google_compute_shared_vpc_service_project" "shared_vpc_attachment" { - count = var.shared_vpc_enabled ? 1 : 0 + count = var.enable_shared_vpc_service_project ? 1 : 0 host_project = var.shared_vpc service_project = google_project.main.project_id @@ -137,6 +137,12 @@ resource "google_compute_shared_vpc_service_project" "shared_vpc_attachment" { ] } +resource "google_compute_shared_vpc_host_project" "shared_vpc_host" { + count = var.enable_shared_vpc_host_project ? 1 : 0 + project = google_project.main.project_id + depends_on = [module.project_services] +} + /****************************************** Default compute service account retrieval *****************************************/ @@ -278,7 +284,7 @@ resource "google_service_account_iam_member" "service_account_grant_to_group" { compute.networkUser role granted to G Suite group, APIs Service account, and Project Service Account *****************************************************************************************************************/ resource "google_project_iam_member" "controlling_group_vpc_membership" { - count = var.shared_vpc_enabled && length(var.shared_vpc_subnets) == 0 ? local.shared_vpc_users_length : 0 + count = var.enable_shared_vpc_service_project && length(var.shared_vpc_subnets) == 0 ? local.shared_vpc_users_length : 0 project = var.shared_vpc role = "roles/compute.networkUser" @@ -294,7 +300,7 @@ resource "google_project_iam_member" "controlling_group_vpc_membership" { *************************************************************************************/ resource "google_compute_subnetwork_iam_member" "service_account_role_to_vpc_subnets" { provider = google-beta - count = var.shared_vpc_enabled && length(var.shared_vpc_subnets) > 0 ? length(var.shared_vpc_subnets) : 0 + count = var.enable_shared_vpc_service_project && length(var.shared_vpc_subnets) > 0 ? length(var.shared_vpc_subnets) : 0 subnetwork = element( split("/", var.shared_vpc_subnets[count.index]), @@ -318,7 +324,7 @@ resource "google_compute_subnetwork_iam_member" "service_account_role_to_vpc_sub resource "google_compute_subnetwork_iam_member" "group_role_to_vpc_subnets" { provider = google-beta - count = var.shared_vpc_enabled && length(var.shared_vpc_subnets) > 0 && var.manage_group ? length(var.shared_vpc_subnets) : 0 + count = var.enable_shared_vpc_service_project && length(var.shared_vpc_subnets) > 0 && var.manage_group ? length(var.shared_vpc_subnets) : 0 subnetwork = element( split("/", var.shared_vpc_subnets[count.index]), index( @@ -341,7 +347,7 @@ resource "google_compute_subnetwork_iam_member" "group_role_to_vpc_subnets" { resource "google_compute_subnetwork_iam_member" "apis_service_account_role_to_vpc_subnets" { provider = google-beta - count = var.shared_vpc_enabled && length(var.shared_vpc_subnets) > 0 ? length(var.shared_vpc_subnets) : 0 + count = var.enable_shared_vpc_service_project && length(var.shared_vpc_subnets) > 0 ? length(var.shared_vpc_subnets) : 0 subnetwork = element( split("/", var.shared_vpc_subnets[count.index]), index( diff --git a/modules/core_project_factory/outputs.tf b/modules/core_project_factory/outputs.tf index 94c2af9a..aa4dc653 100644 --- a/modules/core_project_factory/outputs.tf +++ b/modules/core_project_factory/outputs.tf @@ -23,7 +23,8 @@ output "project_id" { concat( [module.project_services.project_id], [google_project.main.project_id], - [var.shared_vpc_enabled ? google_compute_shared_vpc_service_project.shared_vpc_attachment[0].id : ""], + [var.enable_shared_vpc_service_project ? google_compute_shared_vpc_service_project.shared_vpc_attachment[0].id : ""], + [var.enable_shared_vpc_host_project ? google_compute_shared_vpc_host_project.shared_vpc_host[0].id : ""], ), 0, ) diff --git a/modules/core_project_factory/variables.tf b/modules/core_project_factory/variables.tf index 58257223..cc5ff9e8 100644 --- a/modules/core_project_factory/variables.tf +++ b/modules/core_project_factory/variables.tf @@ -182,11 +182,17 @@ variable "disable_dependent_services" { type = bool } -variable "shared_vpc_enabled" { - description = "If shared VPC should be used" +variable "enable_shared_vpc_service_project" { + description = "If this project should be attached to a shared VPC. If true, you must set shared_vpc variable." type = bool } +variable "enable_shared_vpc_host_project" { + description = "If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false." + type = bool + default = false +} + variable "python_interpreter_path" { description = "Python interpreter path for precondition check script." type = string diff --git a/modules/gsuite_enabled/README.md b/modules/gsuite_enabled/README.md index b139a0eb..b4dee107 100644 --- a/modules/gsuite_enabled/README.md +++ b/modules/gsuite_enabled/README.md @@ -75,6 +75,7 @@ The roles granted are specifically: | disable\_dependent\_services | Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed. | string | `"true"` | no | | disable\_services\_on\_destroy | Whether project services will be disabled when the resources are destroyed | string | `"true"` | no | | domain | The domain name (optional). | string | `""` | no | +| enable\_shared\_vpc\_host\_project | If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false. | bool | `"false"` | no | | folder\_id | The ID of a folder to host this project | string | `""` | no | | group\_name | A group to control the project by being assigned group_role - defaults to $${project_name}-editors | string | `""` | no | | group\_role | The role to give the controlling group (group_name) over the project (defaults to project editor) | string | `"roles/editor"` | no | diff --git a/modules/gsuite_enabled/main.tf b/modules/gsuite_enabled/main.tf index 243bb10e..4952f0d6 100644 --- a/modules/gsuite_enabled/main.tf +++ b/modules/gsuite_enabled/main.tf @@ -79,7 +79,8 @@ module "project-factory" { name = var.name project_id = var.project_id shared_vpc = var.shared_vpc - shared_vpc_enabled = var.shared_vpc_enabled + enable_shared_vpc_service_project = var.shared_vpc_enabled + enable_shared_vpc_host_project = var.enable_shared_vpc_host_project billing_account = var.billing_account folder_id = var.folder_id sa_role = var.sa_role diff --git a/modules/gsuite_enabled/variables.tf b/modules/gsuite_enabled/variables.tf index 75868c2a..f5ea689e 100644 --- a/modules/gsuite_enabled/variables.tf +++ b/modules/gsuite_enabled/variables.tf @@ -177,6 +177,12 @@ variable "shared_vpc_enabled" { default = false } +variable "enable_shared_vpc_host_project" { + description = "If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false." + type = bool + default = false +} + variable "python_interpreter_path" { description = "Python interpreter path for precondition check script." type = string diff --git a/modules/shared_vpc/main.tf b/modules/shared_vpc/main.tf index b170b43e..aed66175 100755 --- a/modules/shared_vpc/main.tf +++ b/modules/shared_vpc/main.tf @@ -37,7 +37,7 @@ module "project-factory" { name = var.name project_id = var.project_id shared_vpc = var.shared_vpc - shared_vpc_enabled = true + enable_shared_vpc_service_project = true billing_account = var.billing_account folder_id = var.folder_id sa_role = var.sa_role diff --git a/test/fixtures/full/versions.tf b/test/fixtures/full/versions.tf index 420dddda..171f3205 100644 --- a/test/fixtures/full/versions.tf +++ b/test/fixtures/full/versions.tf @@ -16,4 +16,9 @@ terraform { required_version = ">=0.12.6, <0.14" + required_providers { + google = { + version = "3.40.0" + } + } } diff --git a/variables.tf b/variables.tf index 93f46178..405a1f1f 100644 --- a/variables.tf +++ b/variables.tf @@ -48,6 +48,12 @@ variable "shared_vpc" { default = "" } +variable "enable_shared_vpc_host_project" { + description = "If this project is a shared VPC host project. If true, you must *not* set shared_vpc variable. Default is false." + type = bool + default = false +} + variable "billing_account" { description = "The ID of the billing account to associate this project with" type = string