From cc602997b7d12b4e103dd5ad60281e517d48f24b Mon Sep 17 00:00:00 2001 From: bharathkkb Date: Mon, 2 Dec 2019 09:21:52 -0600 Subject: [PATCH 01/10] modify example, fixture, obj for healthchecks --- .kitchen.yml | 5 +++ examples/app_engine/README.md | 15 +++---- examples/app_engine/main.tf | 42 +++++++++++++++---- examples/app_engine/outputs.tf | 18 ++++++-- examples/app_engine/variables.tf | 29 ++++++------- modules/app_engine/variables.tf | 4 +- test/fixtures/app_engine/main.tf | 22 ++++++++++ test/fixtures/app_engine/outputs.tf | 35 ++++++++++++++++ test/fixtures/app_engine/variables.tf | 33 +++++++++++++++ .../controls/app-engine.rb | 5 +-- test/integration/app_engine/inspec.yml | 10 +++++ 11 files changed, 177 insertions(+), 41 deletions(-) create mode 100644 test/fixtures/app_engine/main.tf create mode 100644 test/fixtures/app_engine/outputs.tf create mode 100644 test/fixtures/app_engine/variables.tf rename test/integration/{full => app_engine}/controls/app-engine.rb (89%) create mode 100644 test/integration/app_engine/inspec.yml diff --git a/.kitchen.yml b/.kitchen.yml index 426942a5..c35dc8b4 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -37,6 +37,11 @@ suites: name: terraform command_timeout: 1800 root_module_directory: test/fixtures/fabric_project + - name: app_engine + driver: + name: terraform + command_timeout: 1800 + root_module_directory: test/fixtures/app_engine # Disabled due to issue #275 # (https://github.com/terraform-google-modules/terraform-google-project-factory/issues/275) # - name: full diff --git a/examples/app_engine/README.md b/examples/app_engine/README.md index b7f6479e..de909b7a 100644 --- a/examples/app_engine/README.md +++ b/examples/app_engine/README.md @@ -17,17 +17,18 @@ Expected variables: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| auth\_domain | The domain to authenticate users with when using App Engine's User API. | string | n/a | yes | -| feature\_settings | A list of maps of optional settings to configure specific App Engine features. | list | `` | no | -| location\_id | The location to serve the app from. | string | `"us-central"` | no | -| project\_id | The project to enable app engine on. | string | n/a | yes | -| serving\_status | The serving status of the app. | string | `"SERVING"` | no | +| billing\_account | The ID of the billing account to associate this project with | string | n/a | yes | +| folder\_id | The ID of a folder to host this project. | string | `""` | no | +| location\_id | The location to serve the app from. | string | `"us-east4"` | no | +| org\_id | The organization ID. | string | n/a | yes | ## Outputs | Name | Description | |------|-------------| -| code\_bucket | The GCS bucket code is being stored in for this app. | -| name | Unique name of the app, usually apps/{PROJECT_ID}. | +| app\_name | Unique name of the app, usually apps/{PROJECT_ID}. | +| default\_hostname | The default hostname for this app. | +| location\_id | The location app engine is serving from | +| project\_id | The project ID where app engine is created | diff --git a/examples/app_engine/main.tf b/examples/app_engine/main.tf index 1ccacf2e..ad1581ca 100644 --- a/examples/app_engine/main.tf +++ b/examples/app_engine/main.tf @@ -14,18 +14,42 @@ * limitations under the License. */ -/****************************************** - Provider configuration - *****************************************/ provider "google" { version = "~> 2.18.1" } +provider "google-beta" { + version = "~> 2.18.1" +} + +provider "null" { + version = "~> 2.1" +} + +provider "random" { + version = "~> 2.2" +} + +resource "random_string" "suffix" { + length = 4 + special = false + upper = false +} + +module "app-engine-project" { + source = "../../" + name = "appeng-${random_string.suffix.result}" + random_project_id = "true" + org_id = var.org_id + folder_id = var.folder_id + billing_account = var.billing_account + activate_apis = [ + "appengine.googleapis.com", + ] +} + module "app-engine" { - source = "../../modules/app_engine" - location_id = var.location_id - auth_domain = var.auth_domain - serving_status = var.serving_status - feature_settings = [{ enabled = true }] - project_id = "example-project" + source = "../../modules/app_engine" + project_id = module.app-engine-project.project_id + location_id = var.location_id } diff --git a/examples/app_engine/outputs.tf b/examples/app_engine/outputs.tf index 4776d59a..7321f3c1 100644 --- a/examples/app_engine/outputs.tf +++ b/examples/app_engine/outputs.tf @@ -14,13 +14,23 @@ * limitations under the License. */ -output "name" { +output "project_id" { + description = "The project ID where app engine is created" + value = module.app-engine-project.project_id +} + +output "app_name" { description = "Unique name of the app, usually apps/{PROJECT_ID}." value = module.app-engine.name } -output "code_bucket" { - description = "The GCS bucket code is being stored in for this app." - value = module.app-engine.code_bucket +output "default_hostname" { + description = "The default hostname for this app." + value = module.app-engine.default_hostname +} + +output "location_id" { + description = "The location app engine is serving from" + value = var.location_id } diff --git a/examples/app_engine/variables.tf b/examples/app_engine/variables.tf index 725ea343..73ed7053 100644 --- a/examples/app_engine/variables.tf +++ b/examples/app_engine/variables.tf @@ -14,26 +14,23 @@ * limitations under the License. */ -variable "project_id" { - description = "The project to enable app engine on." +variable "org_id" { + description = "The organization ID." + type = string } -variable "location_id" { - description = "The location to serve the app from." - default = "us-central" -} - -variable "auth_domain" { - description = "The domain to authenticate users with when using App Engine's User API." +variable "folder_id" { + description = "The ID of a folder to host this project." + type = string + default = "" } -variable "serving_status" { - description = "The serving status of the app." - default = "SERVING" +variable "billing_account" { + description = "The ID of the billing account to associate this project with" + type = string } -variable "feature_settings" { - description = "A list of maps of optional settings to configure specific App Engine features." - type = list - default = [{ enabled = true }] +variable "location_id" { + description = "The location to serve the app from." + default = "us-east4" } diff --git a/modules/app_engine/variables.tf b/modules/app_engine/variables.tf index a01ff84a..d30a343a 100644 --- a/modules/app_engine/variables.tf +++ b/modules/app_engine/variables.tf @@ -35,7 +35,7 @@ variable "serving_status" { variable "feature_settings" { description = "A list of maps of optional settings to configure specific App Engine features." - type = list - default = [{ enabled = true }] + type = list(object({ split_health_checks = bool })) + default = [{ split_health_checks = true }] } diff --git a/test/fixtures/app_engine/main.tf b/test/fixtures/app_engine/main.tf new file mode 100644 index 00000000..9ce02c73 --- /dev/null +++ b/test/fixtures/app_engine/main.tf @@ -0,0 +1,22 @@ +/** + * Copyright 2019 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. + */ + +module "app-eng" { + source = "../../../examples/app_engine" + org_id = var.org_id + folder_id = var.folder_id + billing_account = var.billing_account +} diff --git a/test/fixtures/app_engine/outputs.tf b/test/fixtures/app_engine/outputs.tf new file mode 100644 index 00000000..409eff1d --- /dev/null +++ b/test/fixtures/app_engine/outputs.tf @@ -0,0 +1,35 @@ +/** + * Copyright 2019 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. + */ + +output "project_id" { + description = "The project ID where app engine is created" + value = module.app-eng.project_id +} + +output "app_name" { + description = "Unique name of the app, usually apps/{PROJECT_ID}." + value = module.app-eng.app_name +} + +output "default_hostname" { + description = "The default hostname for this app." + value = module.app-eng.default_hostname +} + +output "region" { + description = "The location app engine is serving from" + value = module.app-eng.location_id +} diff --git a/test/fixtures/app_engine/variables.tf b/test/fixtures/app_engine/variables.tf new file mode 100644 index 00000000..dd6b508d --- /dev/null +++ b/test/fixtures/app_engine/variables.tf @@ -0,0 +1,33 @@ +/** + * Copyright 2019 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. + */ + +variable "org_id" { + description = "The organization ID." + type = string +} + +variable "folder_id" { + description = "The ID of a folder to host this project." + type = string + default = "" +} + +variable "billing_account" { + description = "The ID of the billing account to associate this project with" + type = string +} + + diff --git a/test/integration/full/controls/app-engine.rb b/test/integration/app_engine/controls/app-engine.rb similarity index 89% rename from test/integration/full/controls/app-engine.rb rename to test/integration/app_engine/controls/app-engine.rb index ab6e6113..b4aea5b8 100644 --- a/test/integration/full/controls/app-engine.rb +++ b/test/integration/app_engine/controls/app-engine.rb @@ -12,9 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -domain = attribute('domain') project_id = attribute('project_id') region = attribute('region') +app_name = attribute('app_name') control 'project-factory-app-engine' do title "Project Factory App Engine configuration" @@ -31,10 +31,9 @@ end end - it { expect(metadata).to include(authDomain: domain) } it { expect(metadata[:featureSettings]).to include({splitHealthChecks: true}) } it { expect(metadata).to include(id: project_id) } - it { expect(metadata).to include(name: "apps/#{project_id}") } + it { expect(metadata).to include(name: app_name) } it { expect(metadata).to include(locationId: region) } it { expect(metadata).to include(servingStatus: 'SERVING') } end diff --git a/test/integration/app_engine/inspec.yml b/test/integration/app_engine/inspec.yml new file mode 100644 index 00000000..fefa7991 --- /dev/null +++ b/test/integration/app_engine/inspec.yml @@ -0,0 +1,10 @@ +name: app_engine +attributes: + - name: project_id + required: true + type: string + - name: region + required: true + - name: app_name + required: true + From 09c4a4cf7c4296c2e53b536ede6d4a3ee65747d1 Mon Sep 17 00:00:00 2001 From: bharathkkb Date: Tue, 10 Dec 2019 21:50:28 -0600 Subject: [PATCH 02/10] review comments --- examples/app_engine/main.tf | 4 ++-- examples/app_engine/outputs.tf | 2 +- modules/app_engine/outputs.tf | 5 +++++ test/fixtures/full/main.tf | 14 -------------- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/examples/app_engine/main.tf b/examples/app_engine/main.tf index ad1581ca..443b0c13 100644 --- a/examples/app_engine/main.tf +++ b/examples/app_engine/main.tf @@ -39,7 +39,7 @@ resource "random_string" "suffix" { module "app-engine-project" { source = "../../" name = "appeng-${random_string.suffix.result}" - random_project_id = "true" + random_project_id = true org_id = var.org_id folder_id = var.folder_id billing_account = var.billing_account @@ -51,5 +51,5 @@ module "app-engine-project" { module "app-engine" { source = "../../modules/app_engine" project_id = module.app-engine-project.project_id - location_id = var.location_id + location_id = "us-east4" } diff --git a/examples/app_engine/outputs.tf b/examples/app_engine/outputs.tf index 7321f3c1..66875f91 100644 --- a/examples/app_engine/outputs.tf +++ b/examples/app_engine/outputs.tf @@ -31,6 +31,6 @@ output "default_hostname" { output "location_id" { description = "The location app engine is serving from" - value = var.location_id + value = module.app-engine.location_id } diff --git a/modules/app_engine/outputs.tf b/modules/app_engine/outputs.tf index 042d2bc0..6c91481c 100644 --- a/modules/app_engine/outputs.tf +++ b/modules/app_engine/outputs.tf @@ -39,3 +39,8 @@ output "default_bucket" { value = google_app_engine_application.main.default_bucket } +output "location_id" { + description = "The location app engine is serving from" + value = google_app_engine_application.main.location_id +} + diff --git a/test/fixtures/full/main.tf b/test/fixtures/full/main.tf index 4b743c51..053b6f74 100644 --- a/test/fixtures/full/main.tf +++ b/test/fixtures/full/main.tf @@ -127,20 +127,6 @@ module "project-factory" { disable_services_on_destroy = "false" } -module "app-engine" { - source = "../../../modules/app_engine" - - project_id = module.project-factory.project_id - location_id = var.region - auth_domain = var.domain - - feature_settings = [ - { - split_health_checks = true - }, - ] -} - resource "google_service_account" "extra_service_account" { project = module.project-factory.project_id account_id = "extra-service-account" From f07145f594aab7897125f4591c051faee2d6ac91 Mon Sep 17 00:00:00 2001 From: "Lim, Choon-Chern (Mike)" Date: Mon, 16 Dec 2019 23:41:51 -0600 Subject: [PATCH 03/10] When deleting service account, deprivilege first to remove IAM binding before deleting service account. main-file draft draft tmpl draft draft draft --- Makefile | 11 + README.md | 6 +- autogen/main.tf.tmpl | 139 +++++++++++ autogen/outputs.tf.tmpl | 89 +++++++ autogen/variables.tf.tmpl | 235 ++++++++++++++++++ autogen/versions.tf.tmpl | 27 ++ helpers/generate_modules/generate_modules.py | 96 +++++++ helpers/generate_modules/requirements.txt | 1 + main.tf | 2 + .../scripts/modify-service-account.sh | 1 + modules/gsuite_enabled/README.md | 10 +- modules/gsuite_enabled/main.tf | 4 +- modules/gsuite_enabled/outputs.tf | 11 +- modules/gsuite_enabled/variables.tf | 70 ++++-- modules/gsuite_enabled/versions.tf | 2 + modules/shared_vpc/main.tf | 2 + modules/shared_vpc/outputs.tf | 2 + modules/shared_vpc/variables.tf | 6 +- modules/shared_vpc/versions.tf | 2 + outputs.tf | 11 +- test/task_helper_functions.sh | 21 ++ variables.tf | 4 +- versions.tf | 2 + 23 files changed, 713 insertions(+), 41 deletions(-) create mode 100755 autogen/main.tf.tmpl create mode 100755 autogen/outputs.tf.tmpl create mode 100755 autogen/variables.tf.tmpl create mode 100644 autogen/versions.tf.tmpl create mode 100755 helpers/generate_modules/generate_modules.py create mode 100644 helpers/generate_modules/requirements.txt create mode 100755 test/task_helper_functions.sh diff --git a/Makefile b/Makefile index b275d19f..99bbc104 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,17 @@ docker_generate_docs: $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ /bin/bash -c 'source /usr/local/bin/task_helper_functions.sh && generate_docs' +# Generate files from autogen +.PHONY: docker_generate +docker_generate: + docker run --rm -it \ + -v "$(CURDIR)":/workspace \ + $(REGISTRY_URL)/${DOCKER_IMAGE_DEVELOPER_TOOLS}:${DOCKER_TAG_VERSION_DEVELOPER_TOOLS} \ + /bin/bash -c 'source /usr/local/bin/task_helper_functions.sh && generate' + # Alias for backwards compatibility .PHONY: generate_docs generate_docs: docker_generate_docs + +.PHONY: generate +generate: docker_generate \ No newline at end of file diff --git a/README.md b/README.md index e715f732..25e85ae7 100644 --- a/README.md +++ b/README.md @@ -151,9 +151,9 @@ determining that location is as follows: | group\_email | The email of the G Suite group with group_name | | project\_bucket\_self\_link | Project's bucket selfLink | | project\_bucket\_url | Project's bucket url | -| project\_id | | -| project\_name | | -| project\_number | | +| project\_id | If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true. | +| project\_name | The name for the project | +| project\_number | The number for the project | | service\_account\_display\_name | The display name of the default service account | | service\_account\_email | The email of the default service account | | service\_account\_id | The id of the default service account | diff --git a/autogen/main.tf.tmpl b/autogen/main.tf.tmpl new file mode 100755 index 00000000..8b8b31a3 --- /dev/null +++ b/autogen/main.tf.tmpl @@ -0,0 +1,139 @@ +/** + * Copyright 2018 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. + */ + +{{ autogeneration_note }} + +{% if gsuite_enabled %} +locals { + group_name = var.group_name != "" ? var.group_name : format("%s-editors", var.name) +} + +/*********************************************** + Make service account member of sa_group group + ***********************************************/ +resource "gsuite_group_member" "service_account_sa_group_member" { + count = var.sa_group != "" ? 1 : 0 + + group = var.sa_group + email = module.project-factory.service_account_email + role = "MEMBER" +} + +/***************************************** + G Suite group information retrieval + *****************************************/ +{% else %} +/***************************************** + Organization info retrieval + *****************************************/ +{% endif %} +module "gsuite_group" { + {% if root_module %} + source = "./modules/gsuite_group" + {% else %} + source = "../gsuite_group" + {% endif %} + + domain = var.domain + {% if gsuite_enabled %} + name = local.group_name + {% else %} + name = var.group_name + {% endif %} + org_id = var.org_id +} + +{% if gsuite_enabled %} +/****************************************** + Gsuite Group Configuration + *****************************************/ +resource "gsuite_group" "group" { + count = var.create_group ? 1 : 0 + + description = "${var.name} project group" + email = module.gsuite_group.email + name = local.group_name +} + +/*********************************************** + Make APIs service account member of api_sa_group + ***********************************************/ +resource "gsuite_group_member" "api_s_account_api_sa_group_member" { + count = var.api_sa_group != "" ? 1 : 0 + + group = var.api_sa_group + email = module.project-factory.api_s_account + role = "MEMBER" +} + +{% endif %} +module "project-factory" { + {% if root_module %} + source = "./modules/core_project_factory" + {% else %} + source = "../core_project_factory" + {% endif %} + + {% if gsuite_enabled %} + group_email = element( + compact( + concat(gsuite_group.group.*.email, [module.gsuite_group.email]), + ), + 0, + ) + {% else %} + group_email = module.gsuite_group.email + {% endif %} + group_role = var.group_role + lien = var.lien + {% if gsuite_enabled %} + manage_group = var.group_name != "" || var.create_group + {% else %} + manage_group = var.group_name != "" ? "true" : "false" + {% endif %} + random_project_id = var.random_project_id + org_id = var.org_id + name = var.name + project_id = var.project_id + shared_vpc = var.shared_vpc + {% if svpc_module %} + shared_vpc_enabled = true + {% elif gsuite_enabled %} + shared_vpc_enabled = var.shared_vpc_enabled + {% elif root_module %} + shared_vpc_enabled = var.shared_vpc != "" + {% endif %} + billing_account = var.billing_account + folder_id = var.folder_id + sa_role = var.sa_role + activate_apis = var.activate_apis + usage_bucket_name = var.usage_bucket_name + usage_bucket_prefix = var.usage_bucket_prefix + credentials_path = var.credentials_path + {% if root_module or gsuite_enabled %} + impersonate_service_account = var.impersonate_service_account + {% endif %} + shared_vpc_subnets = var.shared_vpc_subnets + labels = var.labels + bucket_project = var.bucket_project + bucket_name = var.bucket_name + bucket_location = var.bucket_location + auto_create_network = var.auto_create_network + disable_services_on_destroy = var.disable_services_on_destroy + default_service_account = var.default_service_account + disable_dependent_services = var.disable_dependent_services + python_interpreter_path = var.python_interpreter_path +} diff --git a/autogen/outputs.tf.tmpl b/autogen/outputs.tf.tmpl new file mode 100755 index 00000000..e56568b8 --- /dev/null +++ b/autogen/outputs.tf.tmpl @@ -0,0 +1,89 @@ +/** + * Copyright 2018 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. + */ + +{{ autogeneration_note }} + +output "project_name" { + description = "The name for the project" + value = module.project-factory.project_name +} + +output "project_id" { + description = "If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true." + value = module.project-factory.project_id +} + +output "project_number" { + description = "The number for the project" + value = module.project-factory.project_number +} + +output "domain" { + value = module.gsuite_group.domain + description = "The organization's domain" +} + +output "group_email" { + value = module.gsuite_group.email + {% if gsuite_enabled %} + description = "The email of the created G Suite group with group_name" + {% else %} + description = "The email of the G Suite group with group_name" + {% endif %} +} +{% if gsuite_enabled %} + +output "group_name" { + value = module.gsuite_group.name + description = "The group_name of the G Suite group" +} +{% endif %} + +output "service_account_id" { + value = module.project-factory.service_account_id + description = "The id of the default service account" +} + +output "service_account_display_name" { + value = module.project-factory.service_account_display_name + description = "The display name of the default service account" +} + +output "service_account_email" { + value = module.project-factory.service_account_email + description = "The email of the default service account" +} + +output "service_account_name" { + value = module.project-factory.service_account_name + description = "The fully-qualified name of the default service account" +} + +output "service_account_unique_id" { + value = module.project-factory.service_account_unique_id + description = "The unique id of the default service account" +} + +output "project_bucket_self_link" { + value = module.project-factory.project_bucket_self_link + description = "Project's bucket selfLink" +} + +output "project_bucket_url" { + value = module.project-factory.project_bucket_url + description = "Project's bucket url" +} + diff --git a/autogen/variables.tf.tmpl b/autogen/variables.tf.tmpl new file mode 100755 index 00000000..1be67e40 --- /dev/null +++ b/autogen/variables.tf.tmpl @@ -0,0 +1,235 @@ +/** + * Copyright 2018 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. + */ + + {{ autogeneration_note }} + +variable "random_project_id" { + description = "Enables project random id generation. Mutually exclusive with project_id being non-empty." + {% if gsuite_enabled %} + default = "false" + type = string + {% else %} + type = bool + default = false + {% endif %} +} + +variable "org_id" { + description = "The organization ID." + type = string +} + +variable "domain" { + description = "The domain name (optional)." + type = string + default = "" +} + +variable "name" { + description = "The name for the project" + type = string +} + +variable "project_id" { + description = "If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true." + type = string + default = "" +} + +variable "shared_vpc" { + description = "The ID of the host project which hosts the shared VPC" + type = string + default = "" +} + +variable "billing_account" { + description = "The ID of the billing account to associate this project with" + type = string +} + +variable "folder_id" { + description = "The ID of a folder to host this project" + type = string + default = "" +} + +variable "group_name" { + description = "A group to control the project by being assigned group_role (defaults to project editor)" + type = string + default = "" +} + +variable "group_role" { + description = "The role to give the controlling group (group_name) over the project (defaults to project editor)" + type = string + default = "roles/editor" +} + +variable "sa_role" { + description = "A role to give the default Service Account for the project (defaults to none)" + type = string + default = "" +} + +variable "activate_apis" { + description = "The list of apis to activate within the project" + type = list(string) + default = ["compute.googleapis.com"] +} + +variable "usage_bucket_name" { + description = "Name of a GCS bucket to store GCE usage reports in (optional)" + type = string + default = "" +} + +variable "usage_bucket_prefix" { + description = "Prefix in the GCS bucket to store GCE usage reports in (optional)" + type = string + default = "" +} + +variable "credentials_path" { + description = "Path to a service account credentials file with rights to run the Project Factory. If this file is absent Terraform will fall back to Application Default Credentials." + type = string + default = "" +} + +{% if root_module or gsuite_enabled %} +variable "impersonate_service_account" { + description = "An optional service account to impersonate. This cannot be used with credentials_path. If this service account is not specified and credentials_path is absent, the module will use Application Default Credentials." + type = string + default = "" +} + +{% endif %} +variable "shared_vpc_subnets" { + description = "List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id)" + type = list(string) + default = [""] +} + +variable "labels" { + description = "Map of labels for project" + type = map(string) + default = {} +} + +variable "bucket_project" { + description = "A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)" + type = string + default = "" +} + +variable "bucket_name" { + description = "A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)" + type = string + default = "" +} + +variable "bucket_location" { + description = "The location for a GCS bucket to create (optional)" + type = string + {% if gsuite_enabled %} + default = "" + {% else %} + default = "US" + {% endif %} +} + +variable "auto_create_network" { + description = "Create the default network" + {% if gsuite_enabled %} + type = string + default = "false" + {% else %} + type = bool + default = false + {% endif %} +} + +variable "lien" { + description = "Add a lien on the project to prevent accidental deletion" + {% if gsuite_enabled %} + default = "false" + type = string + {% else %} + type = bool + default = false + {% endif %} +} + +variable "disable_services_on_destroy" { + description = "Whether project services will be disabled when the resources are destroyed" + {% if svpc_module %} + default = true + type = bool + {% else %} + default = "true" + type = string + {% endif %} +} + +variable "default_service_account" { + description = "Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`." + default = "disable" + type = string +} + +variable "disable_dependent_services" { + description = "Whether services that are enabled and which depend on this service should also be disabled when this service is destroyed." + {% if gsuite_enabled %} + default = "true" + type = string + {% else %} + default = true + type = bool + {% endif %} +} + +{% if svpc_module or gsuite_enabled %} +variable "shared_vpc_enabled" { + description = "If shared VPC should be used" + type = bool + default = false +} + +{% endif %} +variable "python_interpreter_path" { + description = "Python interpreter path for precondition check script." + type = string + default = "python3" +} +{% if gsuite_enabled %} + +variable "create_group" { + type = bool + description = "Whether to create the group or not" + default = false +} + +variable "sa_group" { + type = string + description = "A G Suite group to place the default Service Account for the project in" + default = "" +} + +variable "api_sa_group" { + type = string + description = "A G Suite group to place the Google APIs Service Account for the project in" + default = "" +} +{% endif %} \ No newline at end of file diff --git a/autogen/versions.tf.tmpl b/autogen/versions.tf.tmpl new file mode 100644 index 00000000..07e78534 --- /dev/null +++ b/autogen/versions.tf.tmpl @@ -0,0 +1,27 @@ +/** + * Copyright 2018 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. + */ + + {{ autogeneration_note }} + +terraform { + required_version = "~> 0.12.6" + {% if gsuite_enabled %} + + required_providers { + gsuite = "~> 0.1" + } + {% endif %} +} diff --git a/helpers/generate_modules/generate_modules.py b/helpers/generate_modules/generate_modules.py new file mode 100755 index 00000000..c014e718 --- /dev/null +++ b/helpers/generate_modules/generate_modules.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 + +# Copyright 2018 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 +# +# https://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. + +import os +import subprocess +import sys + +from jinja2 import Environment, FileSystemLoader + +TEMPLATE_FOLDER = "./autogen" +BASE_TEMPLATE_OPTIONS = { + 'autogeneration_note': '// This file was automatically generated ' + + 'from a template in {folder}'.format( + folder=TEMPLATE_FOLDER + ), +} + + +class Module(object): + path = None + options = {} + + def __init__(self, path, template_options): + self.path = path + self.options = template_options + + def template_options(self, base): + return {k: v for d in [base, self.options] for k, v in d.items()} + + +MODULES = [ + Module("./", { + 'root_module': True + }), + + Module("./modules/shared_vpc", { + 'svpc_module': True, + }), + Module("./modules/gsuite_enabled", { + 'gsuite_enabled': True, + }) +] +DEVNULL_FILE = open(os.devnull, 'w') + + +def main(argv): + env = Environment( + keep_trailing_newline=True, + loader=FileSystemLoader(TEMPLATE_FOLDER), + trim_blocks=True, + lstrip_blocks=True, + ) + templates = env.list_templates() + for module in MODULES: + for template_file in templates: + template = env.get_template(template_file) + if template_file.endswith(".tf.tmpl"): + template_file = template_file.replace(".tf.tmpl", ".tf") + rendered = template.render( + module.template_options(BASE_TEMPLATE_OPTIONS) + ) + with open(os.path.join(module.path, template_file), "w") as f: + f.write(rendered) + if template_file.endswith(".sh"): + os.chmod(os.path.join(module.path, template_file), 0o755) + # Call terraform fmt for module folder + print ("terraform fmt %s" % module.path) + subprocess.call( + [ + "terraform", + "fmt", + "-write=true", + module.path + ], + stdout=DEVNULL_FILE, + stderr=subprocess.STDOUT + ) + + DEVNULL_FILE.close() + + +if __name__ == "__main__": + main(sys.argv) diff --git a/helpers/generate_modules/requirements.txt b/helpers/generate_modules/requirements.txt new file mode 100644 index 00000000..8ce973e9 --- /dev/null +++ b/helpers/generate_modules/requirements.txt @@ -0,0 +1 @@ +Jinja2 diff --git a/main.tf b/main.tf index 272ffdc0..c0fd9fd8 100644 --- a/main.tf +++ b/main.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + /***************************************** Organization info retrieval *****************************************/ diff --git a/modules/core_project_factory/scripts/modify-service-account.sh b/modules/core_project_factory/scripts/modify-service-account.sh index 0935a502..84712351 100755 --- a/modules/core_project_factory/scripts/modify-service-account.sh +++ b/modules/core_project_factory/scripts/modify-service-account.sh @@ -113,6 +113,7 @@ disable_sa() { # Perform specified action of default service account. case $SA_ACTION in delete) + depriviledge_sa delete_sa ;; depriviledge) depriviledge_sa ;; diff --git a/modules/gsuite_enabled/README.md b/modules/gsuite_enabled/README.md index 21d74260..617884c3 100644 --- a/modules/gsuite_enabled/README.md +++ b/modules/gsuite_enabled/README.md @@ -72,9 +72,9 @@ The roles granted are specifically: | 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 | | 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\_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 | -| impersonate\_service\_account | An optional service account to impersonate. If this service account is not specified, Terraform will fall back to credential file or Application Default Credentials. | string | `""` | no | +| impersonate\_service\_account | An optional service account to impersonate. This cannot be used with credentials_path. If this service account is not specified and credentials_path is absent, the module will use Application Default Credentials. | string | `""` | no | | labels | Map of labels for project | map(string) | `` | no | | lien | Add a lien on the project to prevent accidental deletion | string | `"false"` | no | | name | The name for the project | string | n/a | yes | @@ -99,9 +99,9 @@ The roles granted are specifically: | group\_name | The group_name of the G Suite group | | project\_bucket\_self\_link | Project's bucket selfLink | | project\_bucket\_url | Project's bucket url | -| project\_id | | -| project\_name | | -| project\_number | | +| project\_id | If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true. | +| project\_name | The name for the project | +| project\_number | The number for the project | | service\_account\_display\_name | The display name of the default service account | | service\_account\_email | The email of the default service account | | service\_account\_id | The id of the default service account | diff --git a/modules/gsuite_enabled/main.tf b/modules/gsuite_enabled/main.tf index 862d27ce..c74bbe5c 100644 --- a/modules/gsuite_enabled/main.tf +++ b/modules/gsuite_enabled/main.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + locals { group_name = var.group_name != "" ? var.group_name : format("%s-editors", var.name) } @@ -63,7 +65,7 @@ resource "gsuite_group_member" "api_s_account_api_sa_group_member" { } module "project-factory" { - source = "../core_project_factory/" + source = "../core_project_factory" group_email = element( compact( diff --git a/modules/gsuite_enabled/outputs.tf b/modules/gsuite_enabled/outputs.tf index cde3e3f7..aed22c8f 100644 --- a/modules/gsuite_enabled/outputs.tf +++ b/modules/gsuite_enabled/outputs.tf @@ -14,16 +14,21 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + output "project_name" { - value = module.project-factory.project_name + description = "The name for the project" + value = module.project-factory.project_name } output "project_id" { - value = module.project-factory.project_id + description = "If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true." + value = module.project-factory.project_id } output "project_number" { - value = module.project-factory.project_number + description = "The number for the project" + value = module.project-factory.project_number } output "domain" { diff --git a/modules/gsuite_enabled/variables.tf b/modules/gsuite_enabled/variables.tf index 912f2977..87a146da 100644 --- a/modules/gsuite_enabled/variables.tf +++ b/modules/gsuite_enabled/variables.tf @@ -14,72 +14,68 @@ * limitations under the License. */ -variable "lien" { - description = "Add a lien on the project to prevent accidental deletion" - default = "false" - type = string -} +// This file was automatically generated from a template in ./autogen variable "random_project_id" { description = "Enables project random id generation. Mutually exclusive with project_id being non-empty." default = "false" + type = string } variable "org_id" { description = "The organization ID." + type = string } variable "domain" { description = "The domain name (optional)." + type = string default = "" } variable "name" { description = "The name for the project" + type = string } variable "project_id" { description = "If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true." + type = string default = "" } variable "shared_vpc" { description = "The ID of the host project which hosts the shared VPC" + type = string default = "" } variable "billing_account" { description = "The ID of the billing account to associate this project with" + type = string } variable "folder_id" { description = "The ID of a folder to host this project" + type = string default = "" } variable "group_name" { - description = "A group to control the project by being assigned group_role - defaults to $${project_name}-editors" + description = "A group to control the project by being assigned group_role (defaults to project editor)" + type = string default = "" } -variable "create_group" { - type = bool - description = "Whether to create the group or not" - default = false -} - variable "group_role" { description = "The role to give the controlling group (group_name) over the project (defaults to project editor)" + type = string default = "roles/editor" } -variable "sa_group" { - description = "A G Suite group to place the default Service Account for the project in" - default = "" -} - variable "sa_role" { description = "A role to give the default Service Account for the project (defaults to none)" + type = string default = "" } @@ -91,21 +87,24 @@ variable "activate_apis" { variable "usage_bucket_name" { description = "Name of a GCS bucket to store GCE usage reports in (optional)" + type = string default = "" } variable "usage_bucket_prefix" { description = "Prefix in the GCS bucket to store GCE usage reports in (optional)" + type = string default = "" } variable "credentials_path" { description = "Path to a service account credentials file with rights to run the Project Factory. If this file is absent Terraform will fall back to Application Default Credentials." + type = string default = "" } variable "impersonate_service_account" { - description = "An optional service account to impersonate. If this service account is not specified, Terraform will fall back to credential file or Application Default Credentials." + description = "An optional service account to impersonate. This cannot be used with credentials_path. If this service account is not specified and credentials_path is absent, the module will use Application Default Credentials." type = string default = "" } @@ -124,27 +123,32 @@ variable "labels" { variable "bucket_project" { description = "A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional)" + type = string default = "" } variable "bucket_name" { description = "A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional)" + type = string default = "" } variable "bucket_location" { description = "The location for a GCS bucket to create (optional)" - default = "" -} - -variable "api_sa_group" { - description = "A G Suite group to place the Google APIs Service Account for the project in" + type = string default = "" } variable "auto_create_network" { description = "Create the default network" + type = string + default = "false" +} + +variable "lien" { + description = "Add a lien on the project to prevent accidental deletion" default = "false" + type = string } variable "disable_services_on_destroy" { @@ -154,7 +158,7 @@ variable "disable_services_on_destroy" { } variable "default_service_account" { - description = "Project default service account setting: can be one of `delete`, `depriviledge`, `disable`, or `keep`." + description = "Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`." default = "disable" type = string } @@ -176,3 +180,21 @@ variable "python_interpreter_path" { type = string default = "python3" } + +variable "create_group" { + type = bool + description = "Whether to create the group or not" + default = false +} + +variable "sa_group" { + type = string + description = "A G Suite group to place the default Service Account for the project in" + default = "" +} + +variable "api_sa_group" { + type = string + description = "A G Suite group to place the Google APIs Service Account for the project in" + default = "" +} diff --git a/modules/gsuite_enabled/versions.tf b/modules/gsuite_enabled/versions.tf index e9f21a7f..8172a246 100644 --- a/modules/gsuite_enabled/versions.tf +++ b/modules/gsuite_enabled/versions.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + terraform { required_version = "~> 0.12.6" diff --git a/modules/shared_vpc/main.tf b/modules/shared_vpc/main.tf index 2542a022..e4da0be5 100755 --- a/modules/shared_vpc/main.tf +++ b/modules/shared_vpc/main.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + /***************************************** Organization info retrieval *****************************************/ diff --git a/modules/shared_vpc/outputs.tf b/modules/shared_vpc/outputs.tf index c18b92bd..67ba00b6 100755 --- a/modules/shared_vpc/outputs.tf +++ b/modules/shared_vpc/outputs.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + output "project_name" { description = "The name for the project" value = module.project-factory.project_name diff --git a/modules/shared_vpc/variables.tf b/modules/shared_vpc/variables.tf index 3d2ff4d6..c7322725 100755 --- a/modules/shared_vpc/variables.tf +++ b/modules/shared_vpc/variables.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + variable "random_project_id" { description = "Enables project random id generation. Mutually exclusive with project_id being non-empty." type = bool @@ -73,6 +75,7 @@ variable "group_role" { variable "sa_role" { description = "A role to give the default Service Account for the project (defaults to none)" + type = string default = "" } @@ -96,6 +99,7 @@ variable "usage_bucket_prefix" { variable "credentials_path" { description = "Path to a service account credentials file with rights to run the Project Factory. If this file is absent Terraform will fall back to Application Default Credentials." + type = string default = "" } @@ -148,7 +152,7 @@ variable "disable_services_on_destroy" { } variable "default_service_account" { - description = "Project default service account setting: can be one of `delete`, `depriviledge`, `disable`, or `keep`." + description = "Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`." default = "disable" type = string } diff --git a/modules/shared_vpc/versions.tf b/modules/shared_vpc/versions.tf index 1a9363a3..07650ff4 100644 --- a/modules/shared_vpc/versions.tf +++ b/modules/shared_vpc/versions.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + terraform { required_version = "~> 0.12.6" } diff --git a/outputs.tf b/outputs.tf index 42db07e1..67ba00b6 100644 --- a/outputs.tf +++ b/outputs.tf @@ -14,16 +14,21 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + output "project_name" { - value = module.project-factory.project_name + description = "The name for the project" + value = module.project-factory.project_name } output "project_id" { - value = module.project-factory.project_id + description = "If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true." + value = module.project-factory.project_id } output "project_number" { - value = module.project-factory.project_number + description = "The number for the project" + value = module.project-factory.project_number } output "domain" { diff --git a/test/task_helper_functions.sh b/test/task_helper_functions.sh new file mode 100755 index 00000000..25cb0e51 --- /dev/null +++ b/test/task_helper_functions.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +# Copyright 2019 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. + +function generate() { + pip3 install --user -r /workspace/helpers/generate_modules/requirements.txt + /workspace/helpers/generate_modules/generate_modules.py +} + diff --git a/variables.tf b/variables.tf index 9e4bf320..5c344bdd 100644 --- a/variables.tf +++ b/variables.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + variable "random_project_id" { description = "Enables project random id generation. Mutually exclusive with project_id being non-empty." type = bool @@ -156,7 +158,7 @@ variable "disable_services_on_destroy" { } variable "default_service_account" { - description = "Project default service account setting: can be one of `delete`, `depriviledge`, `disable`, or `keep`." + description = "Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`." default = "disable" type = string } diff --git a/versions.tf b/versions.tf index 1a9363a3..07650ff4 100644 --- a/versions.tf +++ b/versions.tf @@ -14,6 +14,8 @@ * limitations under the License. */ +// This file was automatically generated from a template in ./autogen + terraform { required_version = "~> 0.12.6" } From e593e4c8bd1e0797254d88c0abc7bf66a6d8f791 Mon Sep 17 00:00:00 2001 From: omazin Date: Wed, 18 Dec 2019 11:12:41 +0300 Subject: [PATCH 04/10] Fix typo. Fix #334. --- CHANGELOG.md | 9 +++++++-- README.md | 2 +- docs/TROUBLESHOOTING.md | 2 +- examples/simple_project/README.md | 2 +- examples/simple_project/variables.tf | 2 +- modules/core_project_factory/main.tf | 8 ++++---- .../scripts/modify-service-account.sh | 14 +++++++------- modules/core_project_factory/variables.tf | 2 +- modules/gsuite_enabled/README.md | 2 +- 9 files changed, 24 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9b1b7f1..4d24050c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ Extending the adopted spec, each change should have a link to its corresponding - The `python_interpreter_path` variable which can be altered to support execution in a Windows environment. [#265] - Support for importing existing projects. [#138] +### Changed + +- Fixed typo in `default_service_account` variable's default value from `depriviledge` to `deprivilege`. [#342] + ## [6.0.0] - 2019-11-26 6.0.0 is a backwards incompatible release. See the [upgrade guide](./docs/upgrading_to_project_factory_v6.0.md) for details. @@ -112,7 +116,7 @@ Extending the adopted spec, each change should have a link to its corresponding ### Fixed -- Precoditions script handles projects with a large number of enabled APIs. [#220] +- Preconditions script handles projects with a large number of enabled APIs. [#220] ## [2.3.0] - 2019-05-28 @@ -120,7 +124,7 @@ Extending the adopted spec, each change should have a link to its corresponding - Feature that toggles authoritative management of project services. [#213] - Option that provides ability to choose the region of the bucket [#207] -- Added option to depriviledge or keep default compute service account. [#186] +- Added option to deprivilege or keep default compute service account. [#186] ### Fixed @@ -280,6 +284,7 @@ Extending the adopted spec, each change should have a link to its corresponding [0.2.1]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v0.1.0...v0.2.0 +[#342]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/342 [#313]: https://github.com/terraform-google-modules/terraform-google-project-factory/issues/313 [#300]: https://github.com/terraform-google-modules/terraform-google-project-factory/issues/300 [#309]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/309 diff --git a/README.md b/README.md index 25e85ae7..4bf92e83 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ determining that location is as follows: | bucket\_name | A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional) | string | `""` | no | | bucket\_project | A project to create a GCS bucket (bucket_name) in, useful for Terraform state (optional) | string | `""` | no | | credentials\_path | Path to a service account credentials file with rights to run the Project Factory. If this file is absent Terraform will fall back to Application Default Credentials. | string | `""` | no | -| default\_service\_account | Project default service account setting: can be one of `delete`, `depriviledge`, `disable`, or `keep`. | string | `"disable"` | no | +| default\_service\_account | Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`. | string | `"disable"` | no | | 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 | diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index d524fb4a..e21dbd6b 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -251,7 +251,7 @@ requires that the default compute service account be in place in the project. In order to deploy an App Engine Flex application into a project created by Project Factory, the default service account must not be disabled (as is the default behavior) or deleted. To prevent the default service account from being deleted, ensure that the `default_service_account` input -is set to either `depriviledge` or `keep`. +is set to either `deprivilege` or `keep`. - - - ### Seed project missing APIs diff --git a/examples/simple_project/README.md b/examples/simple_project/README.md index 40427563..5e98f618 100644 --- a/examples/simple_project/README.md +++ b/examples/simple_project/README.md @@ -15,7 +15,7 @@ Expected variables: |------|-------------|:----:|:-----:|:-----:| | billing\_account | The ID of the billing account to associate this project with | string | n/a | yes | | credentials\_path | Path to a service account credentials file with rights to run the Project Factory. If this file is absent Terraform will fall back to Application Default Credentials. | string | `""` | no | -| default\_service\_account | Project default service account setting: can be one of `delete`, `depriviledge`, `disable`, or `keep`. | string | n/a | yes | +| default\_service\_account | Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`. | string | n/a | yes | | organization\_id | The organization id for the associated services | string | n/a | yes | ## Outputs diff --git a/examples/simple_project/variables.tf b/examples/simple_project/variables.tf index 9bfe288c..0e1a8789 100644 --- a/examples/simple_project/variables.tf +++ b/examples/simple_project/variables.tf @@ -28,6 +28,6 @@ variable "credentials_path" { } variable "default_service_account" { - description = "Project default service account setting: can be one of `delete`, `depriviledge`, `disable`, or `keep`." + description = "Project default service account setting: can be one of `delete`, `deprivilege`, `disable`, or `keep`." } diff --git a/modules/core_project_factory/main.tf b/modules/core_project_factory/main.tf index 0ae87f05..5624b7a0 100644 --- a/modules/core_project_factory/main.tf +++ b/modules/core_project_factory/main.tf @@ -209,10 +209,10 @@ EOD } /********************************************* - Default compute service account depriviledge + Default compute service account deprivilege ********************************************/ -resource "null_resource" "depriviledge_default_compute_service_account" { - count = var.default_service_account == "depriviledge" ? 1 : 0 +resource "null_resource" "deprivilege_default_compute_service_account" { + count = var.default_service_account == "deprivilege" ? 1 : 0 provisioner "local-exec" { command = < Date: Wed, 18 Dec 2019 11:19:20 +0300 Subject: [PATCH 05/10] Update change log. --- CHANGELOG.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d24050c..a675cf87 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,8 @@ Extending the adopted spec, each change should have a link to its corresponding ### Changed -- Fixed typo in `default_service_account` variable's default value from `depriviledge` to `deprivilege`. [#342] +- When deleting a service account, deprivilege first to remove IAM binding [#341] +- Fixed typo in `default_service_account` variable's default value from `depriviledge` to `deprivilege`. [#345] ## [6.0.0] - 2019-11-26 @@ -284,7 +285,8 @@ Extending the adopted spec, each change should have a link to its corresponding [0.2.1]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v0.1.0...v0.2.0 -[#342]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/342 +[#345]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/345 +[#341]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/341 [#313]: https://github.com/terraform-google-modules/terraform-google-project-factory/issues/313 [#300]: https://github.com/terraform-google-modules/terraform-google-project-factory/issues/300 [#309]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/309 From 73d56a2820cc88e2a2ebecc7b6ece7ca8450ffbf Mon Sep 17 00:00:00 2001 From: Aaron Lane <10655063+aaron-lane@users.noreply.github.com> Date: Wed, 18 Dec 2019 11:10:53 -0500 Subject: [PATCH 06/10] Move #345 to Fixed in CHANGELOG --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a675cf87..bc24daec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ Extending the adopted spec, each change should have a link to its corresponding ### Changed - When deleting a service account, deprivilege first to remove IAM binding [#341] + +### Fixed + - Fixed typo in `default_service_account` variable's default value from `depriviledge` to `deprivilege`. [#345] ## [6.0.0] - 2019-11-26 From 3ce165356c54f544cdae3a3a8bda4487d121ff96 Mon Sep 17 00:00:00 2001 From: Aaron Lane <10655063+aaron-lane@users.noreply.github.com> Date: Wed, 18 Dec 2019 11:24:57 -0500 Subject: [PATCH 07/10] Add #324, #331, #338, 6.1.0 to CHANGELOG --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc24daec..d5e17d42 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ Extending the adopted spec, each change should have a link to its corresponding ## [Unreleased] +## [6.1.0] - 2019-12-18 + ### Added - The `python_interpreter_path` variable which can be altered to support execution in a Windows environment. [#265] @@ -16,10 +18,13 @@ Extending the adopted spec, each change should have a link to its corresponding ### Changed - When deleting a service account, deprivilege first to remove IAM binding [#341] +- The preconditions script checks for the existence of `gcloud`. [#331] +- The service account setup script only requests the specified project. [#338] ### Fixed - Fixed typo in `default_service_account` variable's default value from `depriviledge` to `deprivilege`. [#345] +- The `feature_settings` variable on the `app_engine` submodule has a valid default. [#324] ## [6.0.0] - 2019-11-26 @@ -256,7 +261,8 @@ Extending the adopted spec, each change should have a link to its corresponding ### ADDED - This is the initial release of the Project Factory Module. -[Unreleased]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v6.0.0...HEAD +[Unreleased]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v6.1.0...HEAD +[6.1.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v6.0.0...v6.1.0 [6.0.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v5.0.0...v6.0.0 [5.0.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v4.0.1...v5.0.0 [4.0.1]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v4.0.0...v4.0.1 @@ -290,6 +296,9 @@ Extending the adopted spec, each change should have a link to its corresponding [#345]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/345 [#341]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/341 +[#338]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/338 +[#331]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/331 +[#324]: https://github.com/terraform-google-modules/terraform-google-project-factory/issues/324 [#313]: https://github.com/terraform-google-modules/terraform-google-project-factory/issues/313 [#300]: https://github.com/terraform-google-modules/terraform-google-project-factory/issues/300 [#309]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/309 From 8041b536d171ee4b90fd6b34758fefe9277b9e0d Mon Sep 17 00:00:00 2001 From: Serhii Kozlovskyi Date: Fri, 20 Dec 2019 17:21:16 +0200 Subject: [PATCH 08/10] Add the generate from tmpl feature --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 99bbc104..61f4d0b7 100644 --- a/Makefile +++ b/Makefile @@ -102,4 +102,4 @@ docker_generate: generate_docs: docker_generate_docs .PHONY: generate -generate: docker_generate \ No newline at end of file +generate: docker_generate From 637c2bcb4821c8beae7b18862ad84cd9b28bbf1c Mon Sep 17 00:00:00 2001 From: Serhii Kozlovskyi Date: Fri, 3 Jan 2020 18:14:07 +0200 Subject: [PATCH 09/10] add pip_executable_path to template --- autogen/main.tf.tmpl | 3 +++ autogen/variables.tf.tmpl | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/autogen/main.tf.tmpl b/autogen/main.tf.tmpl index 8b8b31a3..5c1640d9 100755 --- a/autogen/main.tf.tmpl +++ b/autogen/main.tf.tmpl @@ -136,4 +136,7 @@ module "project-factory" { default_service_account = var.default_service_account disable_dependent_services = var.disable_dependent_services python_interpreter_path = var.python_interpreter_path + {% if root_module %} + pip_executable_path = var.pip_executable_path + {% endif %} } diff --git a/autogen/variables.tf.tmpl b/autogen/variables.tf.tmpl index 1be67e40..dd6ba249 100755 --- a/autogen/variables.tf.tmpl +++ b/autogen/variables.tf.tmpl @@ -213,6 +213,14 @@ variable "python_interpreter_path" { type = string default = "python3" } +{% if root_module %} + +variable "pip_executable_path" { + description = "Pip executable path for precondition requirements.txt install." + type = string + default = "pip3" +} +{% endif %} {% if gsuite_enabled %} variable "create_group" { From 6fdf35d58e4d26a9a8bd3c7aa00a4709e8f57ee5 Mon Sep 17 00:00:00 2001 From: Serhii Kozlovskyi Date: Sun, 19 Jan 2020 21:07:49 +0200 Subject: [PATCH 10/10] change templates according latest release --- README.md | 1 - autogen/main.tf.tmpl | 18 ++++++++++++ autogen/variables.tf.tmpl | 24 ++++++++++++++-- modules/gsuite_enabled/variables.tf | 43 +++++++++++++---------------- outputs.tf | 4 --- 5 files changed, 58 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 8b2c520a..372bd78f 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,6 @@ determining that location is as follows: | Name | Description | |------|-------------| -| budget\_name | The name of the budget if created | | domain | The organization's domain | | group\_email | The email of the G Suite group with group_name | | project\_bucket\_self\_link | Project's bucket selfLink | diff --git a/autogen/main.tf.tmpl b/autogen/main.tf.tmpl index 5c1640d9..61c621f0 100755 --- a/autogen/main.tf.tmpl +++ b/autogen/main.tf.tmpl @@ -140,3 +140,21 @@ module "project-factory" { pip_executable_path = var.pip_executable_path {% endif %} } + +/****************************************** + Billing budget to create if amount is set + *****************************************/ +module "budget" { + {% if root_module %} + source = "./modules/budget" + {% else %} + source = "../budget" + {% endif %} + create_budget = var.budget_amount != null + + projects = [module.project-factory.project_id] + billing_account = var.billing_account + amount = var.budget_amount + alert_spent_percents = var.budget_alert_spent_percents + alert_pubsub_topic = var.budget_alert_pubsub_topic +} diff --git a/autogen/variables.tf.tmpl b/autogen/variables.tf.tmpl index dd6ba249..20f7aa0c 100755 --- a/autogen/variables.tf.tmpl +++ b/autogen/variables.tf.tmpl @@ -17,7 +17,7 @@ {{ autogeneration_note }} variable "random_project_id" { - description = "Enables project random id generation. Mutually exclusive with project_id being non-empty." + description = "Adds a suffix of 4 random characters to the `project_id`" {% if gsuite_enabled %} default = "false" type = string @@ -44,7 +44,7 @@ variable "name" { } variable "project_id" { - description = "If provided, the project uses the given project ID. Mutually exclusive with random_project_id being true." + description = "The ID to give the project. If not provided, the `name` will be used." type = string default = "" } @@ -240,4 +240,22 @@ variable "api_sa_group" { description = "A G Suite group to place the Google APIs Service Account for the project in" default = "" } -{% endif %} \ No newline at end of file +{% endif %} + +variable "budget_amount" { + description = "The amount to use for a budget alert" + type = number + default = null +} + +variable "budget_alert_pubsub_topic" { + description = "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}`" + type = string + default = null +} + +variable "budget_alert_spent_percents" { + description = "A list of percentages of the budget to alert on when threshold is exceeded" + type = list(number) + default = [0.5, 0.7, 1.0] +} diff --git a/modules/gsuite_enabled/variables.tf b/modules/gsuite_enabled/variables.tf index e008058a..c327f0bc 100644 --- a/modules/gsuite_enabled/variables.tf +++ b/modules/gsuite_enabled/variables.tf @@ -40,6 +40,7 @@ variable "name" { variable "project_id" { description = "The ID to give the project. If not provided, the `name` will be used." + type = string default = "" } @@ -66,12 +67,6 @@ variable "group_name" { default = "" } -variable "create_group" { - type = bool - description = "Whether to create the group or not" - default = false -} - variable "group_role" { description = "The role to give the controlling group (group_name) over the project (defaults to project editor)" type = string @@ -186,24 +181,6 @@ variable "python_interpreter_path" { default = "python3" } -variable "budget_amount" { - description = "The amount to use for a budget alert" - type = number - default = null -} - -variable "budget_alert_pubsub_topic" { - description = "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}`" - type = string - default = null -} - -variable "budget_alert_spent_percents" { - description = "A list of percentages of the budget to alert on when threshold is exceeded" - type = list(number) - default = [0.5, 0.7, 1.0] -} - variable "create_group" { type = bool description = "Whether to create the group or not" @@ -221,3 +198,21 @@ variable "api_sa_group" { description = "A G Suite group to place the Google APIs Service Account for the project in" default = "" } + +variable "budget_amount" { + description = "The amount to use for a budget alert" + type = number + default = null +} + +variable "budget_alert_pubsub_topic" { + description = "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}`" + type = string + default = null +} + +variable "budget_alert_spent_percents" { + description = "A list of percentages of the budget to alert on when threshold is exceeded" + type = list(number) + default = [0.5, 0.7, 1.0] +} diff --git a/outputs.tf b/outputs.tf index 233535c9..67ba00b6 100644 --- a/outputs.tf +++ b/outputs.tf @@ -76,7 +76,3 @@ output "project_bucket_url" { description = "Project's bucket url" } -output "budget_name" { - value = module.budget.name - description = "The name of the budget if created" -}