From 7a8b7baaf2b1ab28c7ab3ea5bb3b27dca10b0ae8 Mon Sep 17 00:00:00 2001 From: Nick Stogner Date: Thu, 24 Jan 2019 09:11:01 -0800 Subject: [PATCH 01/13] Break out deprecated app_engine arg into its own resource/module --- main.tf | 6 ++++- modules/app_engine/main.tf | 10 ++++++++ modules/app_engine/outputs.tf | 2 ++ modules/app_engine/variables.tf | 28 ++++++++++++++++++++ modules/core_project_factory/main.tf | 18 +++++++------ modules/core_project_factory/variables.tf | 31 ++++++++++++++++++----- modules/gsuite_enabled/main.tf | 6 ++++- modules/gsuite_enabled/variables.tf | 31 ++++++++++++++++++----- test/fixtures/full/main.tf | 17 ++++++------- test/fixtures/minimal/main.tf | 7 ++--- test/fixtures/shared/variables.tf | 3 +-- variables.tf | 26 ++++++++++++++----- 12 files changed, 143 insertions(+), 42 deletions(-) create mode 100644 modules/app_engine/main.tf create mode 100644 modules/app_engine/outputs.tf create mode 100644 modules/app_engine/variables.tf diff --git a/main.tf b/main.tf index b7d78888..f8046e44 100755 --- a/main.tf +++ b/main.tf @@ -48,6 +48,10 @@ module "project-factory" { bucket_project = "${var.bucket_project}" bucket_name = "${var.bucket_name}" auto_create_network = "${var.auto_create_network}" - app_engine = "${var.app_engine}" disable_services_on_destroy = "${var.disable_services_on_destroy}" + app_engine_enabled = "${var.app_engine_enabled}" + app_engine_location_id = "${var.app_engine_location_id}" + app_engine_auth_domain = "${var.app_engine_auth_domain}" + app_engine_serving_status = "${var.app_engine_serving_status}" + app_engine_feature_settings = "${var.app_engine_feature_settings}" } diff --git a/modules/app_engine/main.tf b/modules/app_engine/main.tf new file mode 100644 index 00000000..4c7334a1 --- /dev/null +++ b/modules/app_engine/main.tf @@ -0,0 +1,10 @@ +resource "google_app_engine_application" "app" { + count = "${var.enabled ? 1 : 0}" + + project = "${var.project_id}" + + location_id = "${var.location_id}" + auth_domain = "${var.auth_domain}" + serving_status = "${var.serving_status}" + feature_settings = "${var.feature_settings}" +} diff --git a/modules/app_engine/outputs.tf b/modules/app_engine/outputs.tf new file mode 100644 index 00000000..b714df14 --- /dev/null +++ b/modules/app_engine/outputs.tf @@ -0,0 +1,2 @@ + +# TODO diff --git a/modules/app_engine/variables.tf b/modules/app_engine/variables.tf new file mode 100644 index 00000000..fcf016ec --- /dev/null +++ b/modules/app_engine/variables.tf @@ -0,0 +1,28 @@ +variable "enabled" { + description = "Enable App Engine." + default = true +} + +variable "project_id" { + description = "The project to enable app engine on." +} + +variable "location_id" { + description = "The location to serve the app from." + default = "" +} + +variable "auth_domain" { + description = "The domain to authenticate users with when using App Engine's User API." + default = "" +} + +variable "serving_status" { + description = "The serving status of the app." + default = "SERVING" +} + +variable "feature_settings" { + description = "A block of optional settings to configure specific App Engine features." + default = [] +} diff --git a/modules/core_project_factory/main.tf b/modules/core_project_factory/main.tf index 5a1686c8..9b050844 100644 --- a/modules/core_project_factory/main.tf +++ b/modules/core_project_factory/main.tf @@ -39,17 +39,11 @@ locals { gke_s_account_fmt = "${local.gke_shared_vpc_enabled ? format("serviceAccount:%s", local.gke_s_account) : ""}" project_bucket_name = "${var.bucket_name != "" ? var.bucket_name : format("%s-state", var.name)}" create_bucket = "${var.bucket_project != "" ? "true" : "false"}" - app_engine_enabled = "${length(keys(var.app_engine)) > 0 ? true : false}" shared_vpc_users = "${compact(list(local.group_id, local.s_account_fmt, local.api_s_account_fmt, local.gke_s_account_fmt))}" # Workaround for https://github.com/hashicorp/terraform/issues/10857 shared_vpc_users_length = "${local.gke_shared_vpc_enabled ? 4 : 3}" - - app_engine_config = { - enabled = "${list(var.app_engine)}" - disabled = "${list()}" - } } resource "null_resource" "preconditions" { @@ -90,11 +84,19 @@ resource "google_project" "main" { labels = "${var.labels}" - app_engine = "${local.app_engine_config["${local.app_engine_enabled ? "enabled" : "disabled"}"]}" - depends_on = ["null_resource.preconditions"] } +module "app-engine" { + source = "../app_engine" + + project_id = "${google_project.main.project_id}" + location_id = "${var.app_engine_location_id}" + auth_domain = "${var.app_engine_auth_domain}" + serving_status = "${var.app_engine_serving_status}" + feature_settings = "${var.app_engine_feature_settings}" +} + /****************************************** Project lien *****************************************/ diff --git a/modules/core_project_factory/variables.tf b/modules/core_project_factory/variables.tf index 5d8fc71e..43561253 100644 --- a/modules/core_project_factory/variables.tf +++ b/modules/core_project_factory/variables.tf @@ -113,14 +113,33 @@ variable "auto_create_network" { default = "false" } -variable "app_engine" { - description = "A map for app engine configuration" - type = "map" - default = {} -} - variable "disable_services_on_destroy" { description = "Whether project services will be disabled when the resources are destroyed" default = "true" type = "string" } + +variable "app_engine_enabled" { + description = "Enable App Engine on the project." + default = false +} + +variable "app_engine_location_id" { + description = "The location to serve the app from." + default = "" +} + +variable "app_engine_auth_domain" { + description = "The domain to authenticate users with when using App Engine's User API." + default = "" +} + +variable "app_engine_serving_status" { + description = "The serving status of the App Engine application." + default = "SERVING" +} + +variable "app_engine_feature_settings" { + description = "A block of optional settings to configure specific App Engine features." + default = [] +} diff --git a/modules/gsuite_enabled/main.tf b/modules/gsuite_enabled/main.tf index 772ca0e7..ed5dba05 100644 --- a/modules/gsuite_enabled/main.tf +++ b/modules/gsuite_enabled/main.tf @@ -85,6 +85,10 @@ module "project-factory" { bucket_project = "${var.bucket_project}" bucket_name = "${var.bucket_name}" auto_create_network = "${var.auto_create_network}" - app_engine = "${var.app_engine}" disable_services_on_destroy = "${var.disable_services_on_destroy}" + app_engine_enabled = "${var.app_engine_enabled}" + app_engine_location_id = "${var.app_engine_location_id}" + app_engine_auth_domain = "${var.app_engine_auth_domain}" + app_engine_serving_status = "${var.app_engine_serving_status}" + app_engine_feature_settings = "${var.app_engine_feature_settings}" } diff --git a/modules/gsuite_enabled/variables.tf b/modules/gsuite_enabled/variables.tf index ee070fb8..db3bb4c5 100644 --- a/modules/gsuite_enabled/variables.tf +++ b/modules/gsuite_enabled/variables.tf @@ -129,14 +129,33 @@ variable "auto_create_network" { default = "false" } -variable "app_engine" { - description = "A map for app engine configuration" - type = "map" - default = {} -} - variable "disable_services_on_destroy" { description = "Whether project services will be disabled when the resources are destroyed" default = "true" type = "string" } + +variable "app_engine_enabled" { + description = "Enable App Engine on the project." + default = false +} + +variable "app_engine_location_id" { + description = "The location to serve the app from." + default = "" +} + +variable "app_engine_auth_domain" { + description = "The domain to authenticate users with when using App Engine's User API." + default = "" +} + +variable "app_engine_serving_status" { + description = "The serving status of the App Engine application." + default = "SERVING" +} + +variable "app_engine_feature_settings" { + description = "A block of optional settings to configure specific App Engine features." + default = [] +} diff --git a/test/fixtures/full/main.tf b/test/fixtures/full/main.tf index f573be04..a138f8bc 100644 --- a/test/fixtures/full/main.tf +++ b/test/fixtures/full/main.tf @@ -102,16 +102,15 @@ module "project-factory" { disable_services_on_destroy = "false" - app_engine { - location_id = "${var.region}" - auth_domain = "${var.domain}" + app_engine_enabled = true + app_engine_location_id = "${var.region}" + app_engine_auth_domain = "${var.domain}" - feature_settings = [ - { - split_health_checks = false - }, - ] - } + app_engine_feature_settings = [ + { + split_health_checks = true + }, + ] } resource "google_service_account" "extra_service_account" { diff --git a/test/fixtures/minimal/main.tf b/test/fixtures/minimal/main.tf index eef451ae..83fbbf34 100644 --- a/test/fixtures/minimal/main.tf +++ b/test/fixtures/minimal/main.tf @@ -25,12 +25,13 @@ provider "google-beta" { } resource "random_string" "suffix" { - length = 5 + length = 5 special = false - upper = false + upper = false } + module "project-factory" { - source = "../../../" + source = "../../../" name = "pf-ci-test-minimal-${random_string.suffix.result}" random_project_id = true diff --git a/test/fixtures/shared/variables.tf b/test/fixtures/shared/variables.tf index f3027de0..99413caf 100644 --- a/test/fixtures/shared/variables.tf +++ b/test/fixtures/shared/variables.tf @@ -22,8 +22,7 @@ variable "folder_id" { default = "" } -variable "domain" { -} +variable "domain" {} variable "usage_bucket_name" { default = "" diff --git a/variables.tf b/variables.tf index 53e317d6..a3b7f214 100755 --- a/variables.tf +++ b/variables.tf @@ -108,12 +108,6 @@ variable "auto_create_network" { default = "false" } -variable "app_engine" { - description = "A map for app engine configuration" - type = "map" - default = {} -} - variable "lien" { description = "Add a lien on the project to prevent accidental deletion" default = "false" @@ -125,3 +119,23 @@ variable "disable_services_on_destroy" { default = "true" type = "string" } + +variable "app_engine_enabled" { + description = "Enable App Engine on the project." +} + +variable "app_engine_location_id" { + description = "The location to serve the app from." +} + +variable "app_engine_auth_domain" { + description = "The domain to authenticate users with when using App Engine's User API." +} + +variable "app_engine_serving_status" { + description = "The serving status of the App Engine application." +} + +variable "app_engine_feature_settings" { + description = "A block of optional settings to configure specific App Engine features." +} From 646a6367c746288734a0949837dd58632d33a5b6 Mon Sep 17 00:00:00 2001 From: Nick Stogner Date: Thu, 24 Jan 2019 13:03:57 -0800 Subject: [PATCH 02/13] Add app engine outputs and fix root module vars --- modules/app_engine/outputs.tf | 45 ++++++++++++++++++++++++- modules/core_project_factory/main.tf | 2 ++ modules/core_project_factory/outputs.tf | 35 ++++++++++++++++--- modules/gsuite_enabled/outputs.tf | 31 +++++++++++++++-- outputs.tf | 31 +++++++++++++++-- variables.tf | 5 +++ 6 files changed, 137 insertions(+), 12 deletions(-) diff --git a/modules/app_engine/outputs.tf b/modules/app_engine/outputs.tf index b714df14..6d614628 100644 --- a/modules/app_engine/outputs.tf +++ b/modules/app_engine/outputs.tf @@ -1,2 +1,45 @@ +/** + * 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. + */ -# TODO +output "name" { + description = "Unique name of the app, usually apps/{PROJECT_ID}." + value = "${google_app_engine_application.app.0.name}" +} + +output "url_dispatch_rule" { + description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." + value = "${google_app_engine_application.app.0.url_dispatch_rule}" +} + +output "code_bucket" { + description = "The GCS bucket code is being stored in for this app." + value = "${google_app_engine_application.app.0.code_bucket}" +} + +output "default_hostname" { + description = "The default hostname for this app." + value = "${google_app_engine_application.app.0.default_hostname}" +} + +output "default_bucket" { + description = "The GCS bucket content is being stored in for this app." + value = "${google_app_engine_application.app.0.default_bucket}" +} + +output "gcr_domain" { + description = "The GCR domain used for storing managed Docker images for this app." + value = "${google_app_engine_application.app.0.gcr_domain}" +} diff --git a/modules/core_project_factory/main.tf b/modules/core_project_factory/main.tf index 9b050844..9cf9ad08 100644 --- a/modules/core_project_factory/main.tf +++ b/modules/core_project_factory/main.tf @@ -90,6 +90,8 @@ resource "google_project" "main" { module "app-engine" { source = "../app_engine" + enabled = "${var.app_engine_enabled}" + project_id = "${google_project.main.project_id}" location_id = "${var.app_engine_location_id}" auth_domain = "${var.app_engine_auth_domain}" diff --git a/modules/core_project_factory/outputs.tf b/modules/core_project_factory/outputs.tf index 0c6e52e8..e2389e61 100644 --- a/modules/core_project_factory/outputs.tf +++ b/modules/core_project_factory/outputs.tf @@ -62,11 +62,6 @@ output "project_bucket_url" { description = "Project's bucket url" } -output "app_engine_enabled" { - value = "${local.app_engine_enabled}" - description = "Whether app engine is enabled" -} - output "api_s_account" { value = "${local.api_s_account}" description = "API service account email" @@ -76,3 +71,33 @@ output "api_s_account_fmt" { value = "${local.api_s_account_fmt}" description = "API service account email formatted for terraform use" } + +output "app_engine_name" { + description = "Unique name of the app, usually apps/{PROJECT_ID}." + value = "${module.app-engine.name}" +} + +output "app_engine_url_dispatch_rule" { + description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." + value = "${module.app-engine.url_dispatch_rule}" +} + +output "app_engine_code_bucket" { + description = "The GCS bucket code is being stored in for this app." + value = "${module.app-engine.code_bucket}" +} + +output "app_engine_default_hostname" { + description = "The default hostname for this app." + value = "${module.app-engine.default_hostname}" +} + +output "app_engine_default_bucket" { + description = "The GCS bucket content is being stored in for this app." + value = "${module.app-engine.default_bucket}" +} + +output "app_engine_gcr_domain" { + description = "The GCR domain used for storing managed Docker images for this app." + value = "${module.app-engine.gcr_domain}" +} diff --git a/modules/gsuite_enabled/outputs.tf b/modules/gsuite_enabled/outputs.tf index 5f4b0ec1..ad57d84d 100644 --- a/modules/gsuite_enabled/outputs.tf +++ b/modules/gsuite_enabled/outputs.tf @@ -67,7 +67,32 @@ output "project_bucket_url" { description = "Project's bucket url" } -output "app_engine_enabled" { - value = "${module.project-factory.app_engine_enabled}" - description = "Whether app engine is enabled" +output "app_engine_name" { + description = "Unique name of the app, usually apps/{PROJECT_ID}." + value = "${module.project-factory.app_engine_name}" +} + +output "app_engine_url_dispatch_rule" { + description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." + value = "${module.project-factory.app_engine_url_dispatch_rule}" +} + +output "app_engine_code_bucket" { + description = "The GCS bucket code is being stored in for this app." + value = "${module.project-factory.app_engine_code_bucket}" +} + +output "app_engine_default_hostname" { + description = "The default hostname for this app." + value = "${module.project-factory.app_engine_default_hostname}" +} + +output "app_engine_default_bucket" { + description = "The GCS bucket content is being stored in for this app." + value = "${module.project-factory.app_engine_default_bucket}" +} + +output "app_engine_gcr_domain" { + description = "The GCR domain used for storing managed Docker images for this app." + value = "${module.project-factory.app_engine_gcr_domain}" } diff --git a/outputs.tf b/outputs.tf index d1a8fd90..09cf5903 100755 --- a/outputs.tf +++ b/outputs.tf @@ -67,7 +67,32 @@ output "project_bucket_url" { description = "Project's bucket url" } -output "app_engine_enabled" { - value = "${module.project-factory.app_engine_enabled}" - description = "Whether app engine is enabled" +output "app_engine_name" { + description = "Unique name of the app, usually apps/{PROJECT_ID}." + value = "${module.project-factory.app_engine_name}" +} + +output "app_engine_url_dispatch_rule" { + description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." + value = "${module.project-factory.app_engine_url_dispatch_rule}" +} + +output "app_engine_code_bucket" { + description = "The GCS bucket code is being stored in for this app." + value = "${module.project-factory.app_engine_code_bucket}" +} + +output "app_engine_default_hostname" { + description = "The default hostname for this app." + value = "${module.project-factory.app_engine_default_hostname}" +} + +output "app_engine_default_bucket" { + description = "The GCS bucket content is being stored in for this app." + value = "${module.project-factory.app_engine_default_bucket}" +} + +output "app_engine_gcr_domain" { + description = "The GCR domain used for storing managed Docker images for this app." + value = "${module.project-factory.app_engine_gcr_domain}" } diff --git a/variables.tf b/variables.tf index a3b7f214..a7d7018d 100755 --- a/variables.tf +++ b/variables.tf @@ -122,20 +122,25 @@ variable "disable_services_on_destroy" { variable "app_engine_enabled" { description = "Enable App Engine on the project." + default = false } variable "app_engine_location_id" { description = "The location to serve the app from." + default = "" } variable "app_engine_auth_domain" { description = "The domain to authenticate users with when using App Engine's User API." + default = "" } variable "app_engine_serving_status" { description = "The serving status of the App Engine application." + default = "SERVING" } variable "app_engine_feature_settings" { description = "A block of optional settings to configure specific App Engine features." + default = [] } From c56e8c1f921c4e858d7f0c6aeb45b753436be8db Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Fri, 22 Feb 2019 10:43:18 -0800 Subject: [PATCH 03/13] Add migration guide for v2.0.0 --- README.md | 7 +++ docs/upgrading_to_project_factory_v2.0.md | 61 +++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 docs/upgrading_to_project_factory_v2.0.md diff --git a/README.md b/README.md index e17432cc..f25a8845 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,13 @@ access, Service Accounts, and API enablement to follow best practices. To include G Suite integration for creating groups and adding Service Accounts into groups, use the [gsuite_enabled module][gsuite-enabled-module]. +## Version + +Current version is 2.0. Upgrade guides: + +- [0.X -> 1.0](./docs/upgrading_to_project_factory_v1.0.md) +- [1.X -> 2.0](./docs/upgrading_to_project_factory_v2.0.md) + ## Usage There are multiple examples included in the [examples](./examples/) folder but simple usage is as follows: diff --git a/docs/upgrading_to_project_factory_v2.0.md b/docs/upgrading_to_project_factory_v2.0.md new file mode 100644 index 00000000..909c7cc3 --- /dev/null +++ b/docs/upgrading_to_project_factory_v2.0.md @@ -0,0 +1,61 @@ +# Upgrading to Project Factory v2.0 (from v1.X) + +The v2.0 release of Project Factory is a backwards incompatible release. It only affects users who utilize the `app_engine` argument. + +## Migration Instructions + +### App Engine + +These steps are only required if you are currently using the `app_engine` argument. + +#### App Engine Argument Changes + +The old version of project factory used a single field for configuring App Engine (`app_engine`): + +```hcl +/// @file main.tf + +module "project-factory" { + ... + app_engine { + location_id = "${var.region}" + auth_domain = "${var.domain}" + + feature_settings = [ + { + split_health_checks = false + }, + ] + } +} +``` + +The new version of project factory uses granular fields prefixed by `app_engine_`. There is also an additional `app_engine_enabled` argument that needs to be set to true. + +```hcl +/// @file main.tf + +module "project-factory" { + ... + app_engine_enabled = true + app_engine_location_id = "${var.region}" + app_engine_auth_domain = "${var.domain}" + + app_engine_feature_settings = [ + { + split_health_checks = true + }, + ] +} +``` + +#### App Engine State Import + +The new implementation uses the `google_app_engine_application` resource which needs to be imported into the current state (make sure to replace `$YOUR_PROJECT_ID`): + +```sh +terraform import module.project-factory.module.project-factory.module.app-engine.google_app_engine_application.app $YOUR_PROJECT_ID +``` + +After importing, you should be good to `terraform` `plan` and `apply`. + From 020487b652669ba869d17bf2f2462d50610584e7 Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Fri, 22 Feb 2019 10:43:51 -0800 Subject: [PATCH 04/13] Update CHANGELOG for v2.0.0 --- CHANGELOG.md | 15 ++++++++++++++- docs/upgrading_to_project_factory_v2.0.md | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65997c54..e433770c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,17 @@ Extending the adopted spec, each change should have a link to its corresponding ## [Unreleased] +## [2.0.0] - 2019-02-22 +2.0.0 is a major backwards incompatible release. See the [upgrade guide](./docs/upgrading_to_project_factory_v2.0.md) for details. + +### ADDED + +- Added separate App Engine module. [#144] + +### REMOVED + +- Removed `app_engine` argument (config block). + ## [1.1.1] - 2019-02-25 ### FIXED - Drop dependency on `gsuite` provider from core module. [#147] @@ -59,7 +70,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/v1.1.1...HEAD +[Unreleased]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v2.0.0...HEAD +[2.0.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v1.1.1...v2.0.0 [1.1.1]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v1.1.0...v1.1.1 [1.1.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v1.0.2...v1.1.0 [1.0.2]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v1.0.1...v1.0.2 @@ -70,6 +82,7 @@ Extending the adopted spec, each change should have a link to its corresponding [0.2.0]: https://github.com/terraform-google-modules/terraform-google-project-factory/compare/v0.1.0...v0.2.0 [#147]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/147 +[#144]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/144 [#143]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/143 [#141]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/141 [#133]: https://github.com/terraform-google-modules/terraform-google-project-factory/pull/133 diff --git a/docs/upgrading_to_project_factory_v2.0.md b/docs/upgrading_to_project_factory_v2.0.md index 909c7cc3..31a72110 100644 --- a/docs/upgrading_to_project_factory_v2.0.md +++ b/docs/upgrading_to_project_factory_v2.0.md @@ -57,5 +57,5 @@ The new implementation uses the `google_app_engine_application` resource which n terraform import module.project-factory.module.project-factory.module.app-engine.google_app_engine_application.app $YOUR_PROJECT_ID ``` -After importing, you should be good to `terraform` `plan` and `apply`. +After importing, run `terraform` `plan` and `apply`. From f301a0e0490a17e6de917fecfef4598c248e63a5 Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Thu, 21 Feb 2019 11:35:36 -0800 Subject: [PATCH 05/13] Update kitchen-terraform container to version with python API client --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 92bf1a4a..f2faca0a 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ SHELL := /usr/bin/env bash # Docker build config variables CREDENTIALS_PATH ?= /cft/workdir/credentials.json DOCKER_ORG := gcr.io/cloud-foundation-cicd -DOCKER_TAG_BASE_KITCHEN_TERRAFORM ?= 0.11.10_216.0.0_1.19.1_0.1.10 +DOCKER_TAG_BASE_KITCHEN_TERRAFORM ?= 0.11.11_235.0.0_1.19.1_0.1.10 DOCKER_REPO_BASE_KITCHEN_TERRAFORM := ${DOCKER_ORG}/cft/kitchen-terraform:${DOCKER_TAG_BASE_KITCHEN_TERRAFORM} all: check_shell check_python check_golang check_terraform check_docker check_base_files test_check_headers check_headers check_trailing_whitespace generate_docs ## Run all linters and update documentation From 5ed157c6b0a96e2330096cf6acd503fe2a998214 Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Thu, 21 Feb 2019 21:54:26 -0800 Subject: [PATCH 06/13] Update integration tests to expect the newly enabled split health checks --- test/integration/full/controls/app-engine.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/full/controls/app-engine.rb b/test/integration/full/controls/app-engine.rb index 873eee71..4d08c01d 100644 --- a/test/integration/full/controls/app-engine.rb +++ b/test/integration/full/controls/app-engine.rb @@ -37,7 +37,7 @@ end it { expect(metadata).to include(authDomain: domain) } - it { expect(metadata).to include(featureSettings: Hash.new) } + it { expect(metadata).to include(featureSettings: {:splitHealthChecks=>true}) } it { expect(metadata).to include(id: project_id) } it { expect(metadata).to include(name: "apps/#{project_id}") } it { expect(metadata).to include(locationId: region) } From b1aef503d81d977b8d7db5f71f8a3179aaa19f7f Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Thu, 21 Feb 2019 11:36:27 -0800 Subject: [PATCH 07/13] Fix python linting errors and file headers --- modules/app_engine/main.tf | 16 ++++++++++++++++ modules/app_engine/outputs.tf | 2 +- modules/app_engine/variables.tf | 16 ++++++++++++++++ .../scripts/preconditions/preconditions.py | 5 ++++- test/helpers/test_migrate.py | 19 +++++++++---------- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/modules/app_engine/main.tf b/modules/app_engine/main.tf index 4c7334a1..7c63e590 100644 --- a/modules/app_engine/main.tf +++ b/modules/app_engine/main.tf @@ -1,3 +1,19 @@ +/** + * 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. + */ + resource "google_app_engine_application" "app" { count = "${var.enabled ? 1 : 0}" diff --git a/modules/app_engine/outputs.tf b/modules/app_engine/outputs.tf index 6d614628..0567c1af 100644 --- a/modules/app_engine/outputs.tf +++ b/modules/app_engine/outputs.tf @@ -1,5 +1,5 @@ /** - * Copyright 2019 Google LLC + * 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. diff --git a/modules/app_engine/variables.tf b/modules/app_engine/variables.tf index fcf016ec..2ee1bf8c 100644 --- a/modules/app_engine/variables.tf +++ b/modules/app_engine/variables.tf @@ -1,3 +1,19 @@ +/** + * 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. + */ + variable "enabled" { description = "Enable App Engine." default = true diff --git a/modules/core_project_factory/scripts/preconditions/preconditions.py b/modules/core_project_factory/scripts/preconditions/preconditions.py index 1cd1dd0a..8f70e3ba 100755 --- a/modules/core_project_factory/scripts/preconditions/preconditions.py +++ b/modules/core_project_factory/scripts/preconditions/preconditions.py @@ -300,7 +300,9 @@ def validate(self, credentials): return req.asdict() @classmethod - def argument_type(cls, string, pat=re.compile(r"[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}")): + def argument_type(cls, + string, + pat=re.compile(r"[A-Z0-9]{6}-[A-Z0-9]{6}-[A-Z0-9]{6}")): if not pat.match(string): msg = "%r is not a valid billing account ID format" % string raise argparse.ArgumentTypeError(msg) @@ -330,6 +332,7 @@ class EmptyStrAction(argparse.Action): """ Convert empty string values parsed by argparse into None. """ + def __call__(self, parser, namespace, values, option_string=None): values = None if values == '' else values setattr(namespace, self.dest, values) diff --git a/test/helpers/test_migrate.py b/test/helpers/test_migrate.py index 515b9a3a..2eea3ce1 100755 --- a/test/helpers/test_migrate.py +++ b/test/helpers/test_migrate.py @@ -14,7 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -import copy import os import sys import unittest @@ -117,15 +116,15 @@ ), ( "module.project-factory.google_project_iam_member.gsuite_group_role", - "module.project-factory.module.project-factory.google_project_iam_member.gsuite_group_role", + "module.project-factory.module.project-factory.google_project_iam_member.gsuite_group_role", # noqa: E501 ), ( "module.project-factory.google_project_service.project_services", - "module.project-factory.module.project-factory.google_project_service.project_services", + "module.project-factory.module.project-factory.google_project_service.project_services", # noqa: E501 ), ( - "module.project-factory.google_service_account.default_service_account", - "module.project-factory.module.project-factory.google_service_account.default_service_account", + "module.project-factory.google_service_account.default_service_account", # noqa: E501 + "module.project-factory.module.project-factory.google_service_account.default_service_account", # noqa: E501 ), ( "module.project-factory.google_service_account_iam_member.service_account_grant_to_group", # noqa: E501 @@ -137,7 +136,7 @@ ), ( "module.project-factory.random_id.random_project_id_suffix", - "module.project-factory.module.project-factory.random_id.random_project_id_suffix", + "module.project-factory.module.project-factory.random_id.random_project_id_suffix", # noqa: E501 ), ] @@ -148,19 +147,19 @@ TERRAFORM_DROPPED_DATA_SOURCES = [ ( "module.project-factory.google_organization.org", - "module.project-factory.module.project-factory.google_organization.org", + "module.project-factory.module.project-factory.google_organization.org", # noqa: E501 ), ( "module.project-factory.null_data_source.data_final_group_email", - "module.project-factory.module.project-factory.null_data_source.data_final_group_email", + "module.project-factory.module.project-factory.null_data_source.data_final_group_email", # noqa: E501 ), ( "module.project-factory.null_data_source.data_given_group_email", - "module.project-factory.module.project-factory.null_data_source.data_given_group_email", + "module.project-factory.module.project-factory.null_data_source.data_given_group_email", # noqa: E501 ), ( "module.project-factory.null_data_source.data_group_email_format", - "module.project-factory.module.project-factory.null_data_source.data_group_email_format", + "module.project-factory.module.project-factory.null_data_source.data_group_email_format", # noqa: E501 ), ] From 3c7b6e8370d1adbb8c6ba2803dec68a92cb19608 Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Fri, 22 Feb 2019 09:58:07 -0800 Subject: [PATCH 08/13] Regenerate documentation --- README.md | 67 ++++++++++------- examples/app_engine/README.md | 14 ++-- examples/gke_shared_vpc/README.md | 12 +-- examples/group_project/README.md | 20 ++--- examples/project-hierarchy/README.md | 16 ++-- examples/simple_project/README.md | 12 +-- modules/core_project_factory/README.md | 75 +++++++++++-------- modules/gsuite_enabled/README.md | 73 ++++++++++-------- modules/gsuite_group/README.md | 5 +- modules/project_services/README.md | 12 +-- .../examples/project_services/README.md | 7 +- test/fixtures/full/README.md | 60 +++++++-------- test/fixtures/minimal/README.md | 58 +++++++------- 13 files changed, 230 insertions(+), 201 deletions(-) diff --git a/README.md b/README.md index f25a8845..fdd4e007 100644 --- a/README.md +++ b/README.md @@ -93,45 +93,54 @@ The roles granted are specifically: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| activate\_apis | The list of apis to activate within the project | list | `` | no | -| app\_engine | A map for app engine configuration | map | `` | no | -| auto\_create\_network | Create the default network | string | `false` | no | -| billing\_account | The ID of the billing account to associate this project with | string | - | yes | -| 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 permissions documented in the readme | string | - | yes | -| disable\_services\_on\_destroy | Whether project services will be disabled when the resources are destroyed | string | `true` | no | +| activate_apis | The list of apis to activate within the project | list | `` | no | +| app_engine_auth_domain | The domain to authenticate users with when using App Engine's User API. | string | `` | no | +| app_engine_enabled | Enable App Engine on the project. | string | `false` | no | +| app_engine_feature_settings | A block of optional settings to configure specific App Engine features. | string | `` | no | +| app_engine_location_id | The location to serve the app from. | string | `` | no | +| app_engine_serving_status | The serving status of the App Engine application. | string | `SERVING` | no | +| auto_create_network | Create the default network | string | `false` | no | +| billing_account | The ID of the billing account to associate this project with | string | - | yes | +| 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 permissions documented in the readme | string | - | yes | +| 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 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 | +| 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 | | labels | Map of labels for project | map | `` | no | | lien | Add a lien on the project to prevent accidental deletion | string | `false` | no | | name | The name for the project | string | - | yes | -| org\_id | The organization ID. | string | - | yes | -| random\_project\_id | Enables project random id generation | string | `false` | no | -| sa\_role | A role to give the default Service Account for the project (defaults to none) | string | `` | no | -| shared\_vpc | The ID of the host project which hosts the shared VPC | string | `` | no | -| shared\_vpc\_subnets | List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id) | list | `` | no | -| usage\_bucket\_name | Name of a GCS bucket to store GCE usage reports in (optional) | string | `` | no | -| usage\_bucket\_prefix | Prefix in the GCS bucket to store GCE usage reports in (optional) | string | `` | no | +| org_id | The organization ID. | string | - | yes | +| random_project_id | Enables project random id generation | string | `false` | no | +| sa_role | A role to give the default Service Account for the project (defaults to none) | string | `` | no | +| shared_vpc | The ID of the host project which hosts the shared VPC | string | `` | no | +| shared_vpc_subnets | List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id) | list | `` | no | +| usage_bucket_name | Name of a GCS bucket to store GCE usage reports in (optional) | string | `` | no | +| usage_bucket_prefix | Prefix in the GCS bucket to store GCE usage reports in (optional) | string | `` | no | ## Outputs | Name | Description | |------|-------------| -| app\_engine\_enabled | Whether app engine is enabled | +| app_engine_code_bucket | The GCS bucket code is being stored in for this app. | +| app_engine_default_bucket | The GCS bucket content is being stored in for this app. | +| app_engine_default_hostname | The default hostname for this app. | +| app_engine_gcr_domain | The GCR domain used for storing managed Docker images for this app. | +| app_engine_name | Unique name of the app, usually apps/{PROJECT_ID}. | +| app_engine_url_dispatch_rule | A list of dispatch rule blocks. Each block has a domain, path, and service field. | | domain | The organization's domain | -| group\_email | The email of the GSuite group with group_name | -| project\_bucket\_self\_link | Project's bucket selfLink | -| project\_bucket\_url | Project's bucket url | -| project\_id | - | -| project\_number | - | -| 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 | -| service\_account\_name | The fully-qualified name of the default service account | -| service\_account\_unique\_id | The unique id of the default service account | +| group_email | The email of the GSuite group with group_name | +| project_bucket_self_link | Project's bucket selfLink | +| project_bucket_url | Project's bucket url | +| project_id | | +| project_number | | +| 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 | +| service_account_name | The fully-qualified name of the default service account | +| service_account_unique_id | The unique id of the default service account | [^]: (autogen_docs_end) diff --git a/examples/app_engine/README.md b/examples/app_engine/README.md index c54dc293..36d619ba 100755 --- a/examples/app_engine/README.md +++ b/examples/app_engine/README.md @@ -18,16 +18,16 @@ Expected variables: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| admin\_email | Admin user email on Gsuite | string | - | yes | -| billing\_account | The ID of the billing account to associate this project with | string | - | yes | -| organization\_id | The organization id for the associated services | string | - | yes | +| admin_email | Admin user email on Gsuite | string | - | yes | +| billing_account | The ID of the billing account to associate this project with | string | - | yes | +| organization_id | The organization id for the associated services | string | - | yes | ## Outputs | Name | Description | |------|-------------| -| app\_engine\_enabled\_example | Whether app engine is enabled | -| domain\_example | The organization's domain | -| project\_info\_example | The ID of the created project | +| app_engine_enabled_example | Whether app engine is enabled | +| domain_example | The organization's domain | +| project_info_example | The ID of the created project | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/examples/gke_shared_vpc/README.md b/examples/gke_shared_vpc/README.md index 0309ca6f..465f1237 100644 --- a/examples/gke_shared_vpc/README.md +++ b/examples/gke_shared_vpc/README.md @@ -29,10 +29,10 @@ More information about GKE with Shared VPC can be found here: https://cloud.goog | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| billing\_account | billing account | string | - | yes | -| credentials\_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | -| org\_id | organization id | string | - | yes | -| shared\_vpc | The ID of the host project which hosts the shared VPC | string | - | yes | -| shared\_vpc\_subnets | List of subnets fully qualified subnet IDs (ie. projects/$PROJECT_ID/regions/$REGION/subnetworks/$SUBNET_ID) | list | `` | no | +| billing_account | billing account | string | - | yes | +| credentials_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | +| org_id | organization id | string | - | yes | +| shared_vpc | The ID of the host project which hosts the shared VPC | string | - | yes | +| shared_vpc_subnets | List of subnets fully qualified subnet IDs (ie. projects/$PROJECT_ID/regions/$REGION/subnetworks/$SUBNET_ID) | list | `` | no | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/examples/group_project/README.md b/examples/group_project/README.md index 74dd78ed..30fd9c28 100644 --- a/examples/group_project/README.md +++ b/examples/group_project/README.md @@ -20,19 +20,19 @@ Expected variables: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| admin\_email | Admin user email on Gsuite. This should be a user account, not a service account. | string | - | yes | -| api\_sa\_group | An existing GSuite group email to place the Google APIs Service Account for the project in | string | - | yes | -| billing\_account | The ID of the billing account to associate this project with | string | - | yes | -| credentials\_file\_path | Service account json auth path | string | - | yes | -| organization\_id | The organization id for the associated services | string | - | yes | -| project\_group\_name | The name of a GSuite group to create for controlling the project | string | - | yes | +| admin_email | Admin user email on Gsuite. This should be a user account, not a service account. | string | - | yes | +| api_sa_group | An existing GSuite group email to place the Google APIs Service Account for the project in | string | - | yes | +| billing_account | The ID of the billing account to associate this project with | string | - | yes | +| credentials_file_path | Service account json auth path | string | - | yes | +| organization_id | The organization id for the associated services | string | - | yes | +| project_group_name | The name of a GSuite group to create for controlling the project | string | - | yes | ## Outputs | Name | Description | |------|-------------| -| domain\_example | The organization's domain | -| group\_email\_example | The email of the created GSuite group | -| project\_info\_example | The ID of the created project | +| domain_example | The organization's domain | +| group_email_example | The email of the created GSuite group | +| project_info_example | The ID of the created project | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/examples/project-hierarchy/README.md b/examples/project-hierarchy/README.md index 1d18b2c1..e2e58501 100644 --- a/examples/project-hierarchy/README.md +++ b/examples/project-hierarchy/README.md @@ -26,17 +26,17 @@ Expected variables: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| admin\_email | Admin user email on Gsuite | string | - | yes | -| billing\_account | The ID of the billing account to associate this project with | string | - | yes | -| credentials\_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | -| organization\_id | The organization id for the associated services | string | - | yes | +| admin_email | Admin user email on Gsuite | string | - | yes | +| billing_account | The ID of the billing account to associate this project with | string | - | yes | +| credentials_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | +| organization_id | The organization id for the associated services | string | - | yes | ## Outputs | Name | Description | |------|-------------| -| domain\_example | The organization's domain | -| project\_info\_example | The ID of the created prod_gke project | -| project\_info\_factory\_example | The ID of the created factory project | +| domain_example | The organization's domain | +| project_info_example | The ID of the created prod_gke project | +| project_info_factory_example | The ID of the created factory project | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/examples/simple_project/README.md b/examples/simple_project/README.md index 32cbaec4..a50b8c13 100755 --- a/examples/simple_project/README.md +++ b/examples/simple_project/README.md @@ -14,15 +14,15 @@ Expected variables: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| billing\_account | The ID of the billing account to associate this project with | string | - | yes | -| credentials\_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | -| organization\_id | The organization id for the associated services | string | - | yes | +| billing_account | The ID of the billing account to associate this project with | string | - | yes | +| credentials_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | +| organization_id | The organization id for the associated services | string | - | yes | ## Outputs | Name | Description | |------|-------------| -| domain\_example | The organization's domain | -| project\_info\_example | The ID of the created project | +| domain_example | The organization's domain | +| project_info_example | The ID of the created project | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/modules/core_project_factory/README.md b/modules/core_project_factory/README.md index 10636363..5fed6620 100644 --- a/modules/core_project_factory/README.md +++ b/modules/core_project_factory/README.md @@ -6,45 +6,54 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| activate\_apis | The list of apis to activate within the project | list | `` | no | -| app\_engine | A map for app engine configuration | map | `` | no | -| auto\_create\_network | Create the default network | string | `false` | no | -| billing\_account | The ID of the billing account to associate this project with | string | - | yes | -| 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 permissions documented in the readme | string | - | yes | -| disable\_services\_on\_destroy | Whether project services will be disabled when the resources are destroyed | string | `true` | no | -| folder\_id | The ID of a folder to host this project | string | `` | no | -| group\_email | The email address of a group to control the project by being assigned group_role. | string | - | yes | -| group\_role | The role to give the controlling group (group_name) over the project. | string | `` | no | +| activate_apis | The list of apis to activate within the project | list | `` | no | +| app_engine_auth_domain | The domain to authenticate users with when using App Engine's User API. | string | `` | no | +| app_engine_enabled | Enable App Engine on the project. | string | `false` | no | +| app_engine_feature_settings | A block of optional settings to configure specific App Engine features. | string | `` | no | +| app_engine_location_id | The location to serve the app from. | string | `` | no | +| app_engine_serving_status | The serving status of the App Engine application. | string | `SERVING` | no | +| auto_create_network | Create the default network | string | `false` | no | +| billing_account | The ID of the billing account to associate this project with | string | - | yes | +| 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 permissions documented in the readme | string | - | yes | +| disable_services_on_destroy | Whether project services will be disabled when the resources are destroyed | string | `true` | no | +| folder_id | The ID of a folder to host this project | string | `` | no | +| group_email | The email address of a group to control the project by being assigned group_role. | string | - | yes | +| group_role | The role to give the controlling group (group_name) over the project. | string | `` | no | | labels | Map of labels for project | map | `` | no | | lien | Add a lien on the project to prevent accidental deletion | string | `false` | no | -| manage\_group | A toggle to indicate if a G Suite group should be managed. | string | `false` | no | +| manage_group | A toggle to indicate if a G Suite group should be managed. | string | `false` | no | | name | The name for the project | string | - | yes | -| org\_id | The organization ID. | string | - | yes | -| random\_project\_id | Enables project random id generation | string | `false` | no | -| sa\_role | A role to give the default Service Account for the project (defaults to none) | string | `` | no | -| shared\_vpc | The ID of the host project which hosts the shared VPC | string | `` | no | -| shared\_vpc\_subnets | List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id) | list | `` | no | -| usage\_bucket\_name | Name of a GCS bucket to store GCE usage reports in (optional) | string | `` | no | -| usage\_bucket\_prefix | Prefix in the GCS bucket to store GCE usage reports in (optional) | string | `` | no | +| org_id | The organization ID. | string | - | yes | +| random_project_id | Enables project random id generation | string | `false` | no | +| sa_role | A role to give the default Service Account for the project (defaults to none) | string | `` | no | +| shared_vpc | The ID of the host project which hosts the shared VPC | string | `` | no | +| shared_vpc_subnets | List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id) | list | `` | no | +| usage_bucket_name | Name of a GCS bucket to store GCE usage reports in (optional) | string | `` | no | +| usage_bucket_prefix | Prefix in the GCS bucket to store GCE usage reports in (optional) | string | `` | no | ## Outputs | Name | Description | |------|-------------| -| api\_s\_account | API service account email | -| api\_s\_account\_fmt | API service account email formatted for terraform use | -| app\_engine\_enabled | Whether app engine is enabled | -| project\_bucket\_name | The name of the projec's bucket | -| project\_bucket\_self\_link | Project's bucket selfLink | -| project\_bucket\_url | Project's bucket url | -| project\_id | - | -| project\_number | - | -| 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 | -| service\_account\_name | The fully-qualified name of the default service account | -| service\_account\_unique\_id | The unique id of the default service account | +| api_s_account | API service account email | +| api_s_account_fmt | API service account email formatted for terraform use | +| app_engine_code_bucket | The GCS bucket code is being stored in for this app. | +| app_engine_default_bucket | The GCS bucket content is being stored in for this app. | +| app_engine_default_hostname | The default hostname for this app. | +| app_engine_gcr_domain | The GCR domain used for storing managed Docker images for this app. | +| app_engine_name | Unique name of the app, usually apps/{PROJECT_ID}. | +| app_engine_url_dispatch_rule | A list of dispatch rule blocks. Each block has a domain, path, and service field. | +| project_bucket_name | The name of the projec's bucket | +| project_bucket_self_link | Project's bucket selfLink | +| project_bucket_url | Project's bucket url | +| project_id | | +| project_number | | +| 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 | +| service_account_name | The fully-qualified name of the default service account | +| service_account_unique_id | The unique id of the default service account | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/modules/gsuite_enabled/README.md b/modules/gsuite_enabled/README.md index 225639e3..47d7c8ce 100644 --- a/modules/gsuite_enabled/README.md +++ b/modules/gsuite_enabled/README.md @@ -59,48 +59,57 @@ The roles granted are specifically: | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| activate\_apis | The list of apis to activate within the project | list | `` | no | -| api\_sa\_group | A GSuite group to place the Google APIs Service Account for the project in | string | `` | no | -| app\_engine | A map for app engine configuration | map | `` | no | -| auto\_create\_network | Create the default network | string | `false` | no | -| billing\_account | The ID of the billing account to associate this project with | string | - | yes | -| 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 | -| create\_group | Whether to create the group or not | string | `false` | no | -| credentials\_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | -| disable\_services\_on\_destroy | Whether project services will be disabled when the resources are destroyed | string | `true` | no | +| activate_apis | The list of apis to activate within the project | list | `` | no | +| api_sa_group | A GSuite group to place the Google APIs Service Account for the project in | string | `` | no | +| app_engine_auth_domain | The domain to authenticate users with when using App Engine's User API. | string | `` | no | +| app_engine_enabled | Enable App Engine on the project. | string | `false` | no | +| app_engine_feature_settings | A block of optional settings to configure specific App Engine features. | string | `` | no | +| app_engine_location_id | The location to serve the app from. | string | `` | no | +| app_engine_serving_status | The serving status of the App Engine application. | string | `SERVING` | no | +| auto_create_network | Create the default network | string | `false` | no | +| billing_account | The ID of the billing account to associate this project with | string | - | yes | +| 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 | +| create_group | Whether to create the group or not | string | `false` | no | +| credentials_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | +| 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\_role | The role to give the controlling group (group_name) over the project (defaults to project editor) | string | `roles/editor` | 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 | | labels | Map of labels for project | map | `` | no | | lien | Add a lien on the project to prevent accidental deletion | string | `false` | no | | name | The name for the project | string | - | yes | -| org\_id | The organization ID. | string | - | yes | -| random\_project\_id | Enables project random id generation | string | `false` | no | -| sa\_group | A GSuite group to place the default Service Account for the project in | string | `` | no | -| sa\_role | A role to give the default Service Account for the project (defaults to none) | string | `` | no | -| shared\_vpc | The ID of the host project which hosts the shared VPC | string | `` | no | -| shared\_vpc\_subnets | List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id) | list | `` | no | -| usage\_bucket\_name | Name of a GCS bucket to store GCE usage reports in (optional) | string | `` | no | -| usage\_bucket\_prefix | Prefix in the GCS bucket to store GCE usage reports in (optional) | string | `` | no | +| org_id | The organization ID. | string | - | yes | +| random_project_id | Enables project random id generation | string | `false` | no | +| sa_group | A GSuite group to place the default Service Account for the project in | string | `` | no | +| sa_role | A role to give the default Service Account for the project (defaults to none) | string | `` | no | +| shared_vpc | The ID of the host project which hosts the shared VPC | string | `` | no | +| shared_vpc_subnets | List of subnets fully qualified subnet IDs (ie. projects/$project_id/regions/$region/subnetworks/$subnet_id) | list | `` | no | +| usage_bucket_name | Name of a GCS bucket to store GCE usage reports in (optional) | string | `` | no | +| usage_bucket_prefix | Prefix in the GCS bucket to store GCE usage reports in (optional) | string | `` | no | ## Outputs | Name | Description | |------|-------------| -| app\_engine\_enabled | Whether app engine is enabled | +| app_engine_code_bucket | The GCS bucket code is being stored in for this app. | +| app_engine_default_bucket | The GCS bucket content is being stored in for this app. | +| app_engine_default_hostname | The default hostname for this app. | +| app_engine_gcr_domain | The GCR domain used for storing managed Docker images for this app. | +| app_engine_name | Unique name of the app, usually apps/{PROJECT_ID}. | +| app_engine_url_dispatch_rule | A list of dispatch rule blocks. Each block has a domain, path, and service field. | | domain | The organization's domain | -| group\_email | The email of the created GSuite group with group_name | -| project\_bucket\_self\_link | Project's bucket selfLink | -| project\_bucket\_url | Project's bucket url | -| project\_id | - | -| project\_number | - | -| 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 | -| service\_account\_name | The fully-qualified name of the default service account | -| service\_account\_unique\_id | The unique id of the default service account | +| group_email | The email of the created GSuite group with group_name | +| project_bucket_self_link | Project's bucket selfLink | +| project_bucket_url | Project's bucket url | +| project_id | | +| project_number | | +| 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 | +| service_account_name | The fully-qualified name of the default service account | +| service_account_unique_id | The unique id of the default service account | [^]: (autogen_docs_end) diff --git a/modules/gsuite_group/README.md b/modules/gsuite_group/README.md index 7dfa43b5..aca1e361 100644 --- a/modules/gsuite_group/README.md +++ b/modules/gsuite_group/README.md @@ -6,9 +6,10 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| +| create_group | Whether to create the group or not | string | `false` | no | | domain | The domain name | string | `` | no | | name | The name of the group. | string | - | yes | -| org\_id | The organization ID. | string | - | yes | +| org_id | The organization ID. | string | - | yes | ## Outputs @@ -17,4 +18,4 @@ | domain | The domain of the group's organization. | | email | The email address of the group. | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/modules/project_services/README.md b/modules/project_services/README.md index 8a4ebbc6..f4a7ecb6 100644 --- a/modules/project_services/README.md +++ b/modules/project_services/README.md @@ -27,15 +27,15 @@ See [examples/project_services](./examples/project_services) for an example. | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| activate\_apis | The list of apis to activate within the project | list | n/a | yes | -| disable\_services\_on\_destroy | Whether project services will be disabled when the resources are destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_on_destroy | string | `"true"` | no | -| enable\_apis | Whether to actually enable the APIs. If false, this module is a no-op. | string | `"true"` | no | -| project\_id | The GCP project you want to enable APIs on | string | n/a | yes | +| activate_apis | The list of apis to activate within the project | list | - | yes | +| disable_services_on_destroy | Whether project services will be disabled when the resources are destroyed. https://www.terraform.io/docs/providers/google/r/google_project_service.html#disable_on_destroy | string | `true` | no | +| enable_apis | Whether to actually enable the APIs. If false, this module is a no-op. | string | `true` | no | +| project_id | The GCP project you want to enable APIs on | string | - | yes | ## Outputs | Name | Description | |------|-------------| -| project\_id | The GCP project you want to enable APIs on | +| project_id | The GCP project you want to enable APIs on | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/modules/project_services/examples/project_services/README.md b/modules/project_services/examples/project_services/README.md index 7a95507a..dd32e673 100755 --- a/modules/project_services/examples/project_services/README.md +++ b/modules/project_services/examples/project_services/README.md @@ -8,17 +8,18 @@ Expected variables: [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| credentials\_path | Path to a Service Account credentials file with permissions documented in the readme | string | n/a | yes | -| project\_id | The GCP project you want to enable APIs on | string | n/a | yes | +| credentials_path | Path to a Service Account credentials file with permissions documented in the readme | string | - | yes | +| project_id | The GCP project you want to enable APIs on | string | - | yes | ## Outputs | Name | Description | |------|-------------| -| project\_id | The GCP project you want to enable APIs on | +| project_id | The GCP project you want to enable APIs on | [^]: (autogen_docs_end) \ No newline at end of file diff --git a/test/fixtures/full/README.md b/test/fixtures/full/README.md index bec6ecef..9086d500 100644 --- a/test/fixtures/full/README.md +++ b/test/fixtures/full/README.md @@ -6,39 +6,39 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| billing\_account | - | string | - | yes | -| create\_group | - | string | `false` | no | -| credentials\_path | - | string | - | yes | -| domain | - | string | - | yes | -| folder\_id | - | string | `` | no | -| group\_name | - | string | `` | no | -| group\_role | - | string | `roles/viewer` | no | -| gsuite\_admin\_account | - | string | - | yes | -| org\_id | - | string | - | yes | -| region | - | string | `us-east4` | no | -| sa\_group | - | string | `` | no | -| sa\_role | - | string | `roles/editor` | no | -| shared\_vpc | - | string | `` | no | -| usage\_bucket\_name | - | string | `` | no | -| usage\_bucket\_prefix | - | string | `` | no | +| billing_account | | string | - | yes | +| create_group | | string | `false` | no | +| credentials_path | | string | - | yes | +| domain | | string | - | yes | +| folder_id | | string | `` | no | +| group_name | | string | `` | no | +| group_role | | string | `roles/viewer` | no | +| gsuite_admin_account | | string | - | yes | +| org_id | | string | - | yes | +| region | | string | `us-east4` | no | +| sa_group | | string | `` | no | +| sa_role | | string | `roles/editor` | no | +| shared_vpc | | string | `` | no | +| usage_bucket_name | | string | `` | no | +| usage_bucket_prefix | | string | `` | no | ## Outputs | Name | Description | |------|-------------| -| credentials\_path | Pass through the `credentials_path` variable so that InSpec can reuse the credentials | -| domain | - | -| extra\_service\_account\_email | - | -| group\_email | - | -| group\_role | - | -| gsuite\_admin\_account | - | -| project\_id | - | -| project\_number | - | -| region | - | -| sa\_role | - | -| service\_account\_email | - | -| shared\_vpc | - | -| usage\_bucket\_name | - | -| usage\_bucket\_prefix | - | +| credentials_path | Pass through the `credentials_path` variable so that InSpec can reuse the credentials | +| domain | | +| extra_service_account_email | | +| group_email | | +| group_role | | +| gsuite_admin_account | | +| project_id | | +| project_number | | +| region | | +| sa_role | | +| service_account_email | | +| shared_vpc | | +| usage_bucket_name | | +| usage_bucket_prefix | | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) diff --git a/test/fixtures/minimal/README.md b/test/fixtures/minimal/README.md index 176aff32..ca17d297 100644 --- a/test/fixtures/minimal/README.md +++ b/test/fixtures/minimal/README.md @@ -6,38 +6,38 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| billing\_account | - | string | - | yes | -| create\_group | - | string | `false` | no | -| credentials\_path | - | string | - | yes | -| domain | - | string | - | yes | -| folder\_id | - | string | `` | no | -| group\_name | - | string | `` | no | -| group\_role | - | string | `roles/viewer` | no | -| gsuite\_admin\_account | - | string | - | yes | -| org\_id | - | string | - | yes | -| region | - | string | `us-east4` | no | -| sa\_group | - | string | `` | no | -| sa\_role | - | string | `roles/editor` | no | -| shared\_vpc | - | string | `` | no | -| usage\_bucket\_name | - | string | `` | no | -| usage\_bucket\_prefix | - | string | `` | no | +| billing_account | | string | - | yes | +| create_group | | string | `false` | no | +| credentials_path | | string | - | yes | +| domain | | string | - | yes | +| folder_id | | string | `` | no | +| group_name | | string | `` | no | +| group_role | | string | `roles/viewer` | no | +| gsuite_admin_account | | string | - | yes | +| org_id | | string | - | yes | +| region | | string | `us-east4` | no | +| sa_group | | string | `` | no | +| sa_role | | string | `roles/editor` | no | +| shared_vpc | | string | `` | no | +| usage_bucket_name | | string | `` | no | +| usage_bucket_prefix | | string | `` | no | ## Outputs | Name | Description | |------|-------------| -| credentials\_path | Pass through the `credentials_path` variable so that InSpec can reuse the credentials | -| domain | - | -| group\_email | - | -| group\_role | - | -| gsuite\_admin\_account | - | -| project\_id | - | -| project\_number | - | -| region | - | -| sa\_role | - | -| service\_account\_email | - | -| shared\_vpc | - | -| usage\_bucket\_name | - | -| usage\_bucket\_prefix | - | +| credentials_path | Pass through the `credentials_path` variable so that InSpec can reuse the credentials | +| domain | | +| group_email | | +| group_role | | +| gsuite_admin_account | | +| project_id | | +| project_number | | +| region | | +| sa_role | | +| service_account_email | | +| shared_vpc | | +| usage_bucket_name | | +| usage_bucket_prefix | | -[^]: (autogen_docs_end) \ No newline at end of file +[^]: (autogen_docs_end) From a34f7d9b7479bd785ee3d17bfd062dfac321442b Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Fri, 22 Feb 2019 10:34:24 -0800 Subject: [PATCH 09/13] Move App Engine components into its own submodule to avoid duplicating module interfaces --- CHANGELOG.md | 1 + docs/upgrading_to_project_factory_v2.0.md | 15 +++++++------- main.tf | 5 ----- modules/app_engine/main.tf | 5 +---- modules/app_engine/variables.tf | 5 ----- modules/core_project_factory/main.tf | 12 ----------- test/fixtures/full/main.tf | 10 +++++---- variables.tf | 25 ----------------------- 8 files changed, 15 insertions(+), 63 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e433770c..f025cc67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Extending the adopted spec, each change should have a link to its corresponding ## [1.1.0] - 2019-02-22 ### ADDED +- Added separate App Engine module. [#134] - Preconditions script checks billing account format. [#117] - Add project_services submodule. [#133] diff --git a/docs/upgrading_to_project_factory_v2.0.md b/docs/upgrading_to_project_factory_v2.0.md index 31a72110..5a43b3ea 100644 --- a/docs/upgrading_to_project_factory_v2.0.md +++ b/docs/upgrading_to_project_factory_v2.0.md @@ -30,18 +30,17 @@ module "project-factory" { } ``` -The new version of project factory uses granular fields prefixed by `app_engine_`. There is also an additional `app_engine_enabled` argument that needs to be set to true. +The new version of project factory uses a new module named `app_engine`. It accepts ```hcl /// @file main.tf -module "project-factory" { - ... - app_engine_enabled = true - app_engine_location_id = "${var.region}" - app_engine_auth_domain = "${var.domain}" +module "app-engine" { + project = "${var.project_id} + location_id = "${var.region}" + auth_domain = "${var.domain}" - app_engine_feature_settings = [ + feature_settings = [ { split_health_checks = true }, @@ -54,7 +53,7 @@ module "project-factory" { The new implementation uses the `google_app_engine_application` resource which needs to be imported into the current state (make sure to replace `$YOUR_PROJECT_ID`): ```sh -terraform import module.project-factory.module.project-factory.module.app-engine.google_app_engine_application.app $YOUR_PROJECT_ID +terraform import module.app-engine.google_app_engine_application.app $YOUR_PROJECT_ID ``` After importing, run `terraform` `plan` and `apply`. diff --git a/main.tf b/main.tf index f8046e44..1acbe9f6 100755 --- a/main.tf +++ b/main.tf @@ -49,9 +49,4 @@ module "project-factory" { bucket_name = "${var.bucket_name}" auto_create_network = "${var.auto_create_network}" disable_services_on_destroy = "${var.disable_services_on_destroy}" - app_engine_enabled = "${var.app_engine_enabled}" - app_engine_location_id = "${var.app_engine_location_id}" - app_engine_auth_domain = "${var.app_engine_auth_domain}" - app_engine_serving_status = "${var.app_engine_serving_status}" - app_engine_feature_settings = "${var.app_engine_feature_settings}" } diff --git a/modules/app_engine/main.tf b/modules/app_engine/main.tf index 7c63e590..338c018b 100644 --- a/modules/app_engine/main.tf +++ b/modules/app_engine/main.tf @@ -15,10 +15,7 @@ */ resource "google_app_engine_application" "app" { - count = "${var.enabled ? 1 : 0}" - - project = "${var.project_id}" - + project = "${var.project_id}" location_id = "${var.location_id}" auth_domain = "${var.auth_domain}" serving_status = "${var.serving_status}" diff --git a/modules/app_engine/variables.tf b/modules/app_engine/variables.tf index 2ee1bf8c..16d1dd66 100644 --- a/modules/app_engine/variables.tf +++ b/modules/app_engine/variables.tf @@ -14,11 +14,6 @@ * limitations under the License. */ -variable "enabled" { - description = "Enable App Engine." - default = true -} - variable "project_id" { description = "The project to enable app engine on." } diff --git a/modules/core_project_factory/main.tf b/modules/core_project_factory/main.tf index 9cf9ad08..61586fb6 100644 --- a/modules/core_project_factory/main.tf +++ b/modules/core_project_factory/main.tf @@ -87,18 +87,6 @@ resource "google_project" "main" { depends_on = ["null_resource.preconditions"] } -module "app-engine" { - source = "../app_engine" - - enabled = "${var.app_engine_enabled}" - - project_id = "${google_project.main.project_id}" - location_id = "${var.app_engine_location_id}" - auth_domain = "${var.app_engine_auth_domain}" - serving_status = "${var.app_engine_serving_status}" - feature_settings = "${var.app_engine_feature_settings}" -} - /****************************************** Project lien *****************************************/ diff --git a/test/fixtures/full/main.tf b/test/fixtures/full/main.tf index a138f8bc..a75da073 100644 --- a/test/fixtures/full/main.tf +++ b/test/fixtures/full/main.tf @@ -101,12 +101,14 @@ module "project-factory" { ] disable_services_on_destroy = "false" +} - app_engine_enabled = true - app_engine_location_id = "${var.region}" - app_engine_auth_domain = "${var.domain}" +module "app-engine" { + project = "${module.project-factory.project_id}" + location_id = "${var.region}" + auth_domain = "${var.domain}" - app_engine_feature_settings = [ + feature_settings = [ { split_health_checks = true }, diff --git a/variables.tf b/variables.tf index a7d7018d..704380a1 100755 --- a/variables.tf +++ b/variables.tf @@ -119,28 +119,3 @@ variable "disable_services_on_destroy" { default = "true" type = "string" } - -variable "app_engine_enabled" { - description = "Enable App Engine on the project." - default = false -} - -variable "app_engine_location_id" { - description = "The location to serve the app from." - default = "" -} - -variable "app_engine_auth_domain" { - description = "The domain to authenticate users with when using App Engine's User API." - default = "" -} - -variable "app_engine_serving_status" { - description = "The serving status of the App Engine application." - default = "SERVING" -} - -variable "app_engine_feature_settings" { - description = "A block of optional settings to configure specific App Engine features." - default = [] -} From 8c48ec00a3a8b757f445f8d49e20240c71e03194 Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Fri, 22 Feb 2019 12:17:57 -0800 Subject: [PATCH 10/13] Fix failing tests --- modules/core_project_factory/outputs.tf | 30 ------------------------- modules/gsuite_enabled/main.tf | 5 ----- modules/gsuite_enabled/outputs.tf | 30 ------------------------- modules/gsuite_enabled/variables.tf | 25 --------------------- outputs.tf | 30 ------------------------- test/fixtures/full/main.tf | 4 +++- 6 files changed, 3 insertions(+), 121 deletions(-) diff --git a/modules/core_project_factory/outputs.tf b/modules/core_project_factory/outputs.tf index e2389e61..d1d05e18 100644 --- a/modules/core_project_factory/outputs.tf +++ b/modules/core_project_factory/outputs.tf @@ -71,33 +71,3 @@ output "api_s_account_fmt" { value = "${local.api_s_account_fmt}" description = "API service account email formatted for terraform use" } - -output "app_engine_name" { - description = "Unique name of the app, usually apps/{PROJECT_ID}." - value = "${module.app-engine.name}" -} - -output "app_engine_url_dispatch_rule" { - description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." - value = "${module.app-engine.url_dispatch_rule}" -} - -output "app_engine_code_bucket" { - description = "The GCS bucket code is being stored in for this app." - value = "${module.app-engine.code_bucket}" -} - -output "app_engine_default_hostname" { - description = "The default hostname for this app." - value = "${module.app-engine.default_hostname}" -} - -output "app_engine_default_bucket" { - description = "The GCS bucket content is being stored in for this app." - value = "${module.app-engine.default_bucket}" -} - -output "app_engine_gcr_domain" { - description = "The GCR domain used for storing managed Docker images for this app." - value = "${module.app-engine.gcr_domain}" -} diff --git a/modules/gsuite_enabled/main.tf b/modules/gsuite_enabled/main.tf index ed5dba05..f207e51b 100644 --- a/modules/gsuite_enabled/main.tf +++ b/modules/gsuite_enabled/main.tf @@ -86,9 +86,4 @@ module "project-factory" { bucket_name = "${var.bucket_name}" auto_create_network = "${var.auto_create_network}" disable_services_on_destroy = "${var.disable_services_on_destroy}" - app_engine_enabled = "${var.app_engine_enabled}" - app_engine_location_id = "${var.app_engine_location_id}" - app_engine_auth_domain = "${var.app_engine_auth_domain}" - app_engine_serving_status = "${var.app_engine_serving_status}" - app_engine_feature_settings = "${var.app_engine_feature_settings}" } diff --git a/modules/gsuite_enabled/outputs.tf b/modules/gsuite_enabled/outputs.tf index ad57d84d..0a78849e 100644 --- a/modules/gsuite_enabled/outputs.tf +++ b/modules/gsuite_enabled/outputs.tf @@ -66,33 +66,3 @@ output "project_bucket_url" { value = "${module.project-factory.project_bucket_url}" description = "Project's bucket url" } - -output "app_engine_name" { - description = "Unique name of the app, usually apps/{PROJECT_ID}." - value = "${module.project-factory.app_engine_name}" -} - -output "app_engine_url_dispatch_rule" { - description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." - value = "${module.project-factory.app_engine_url_dispatch_rule}" -} - -output "app_engine_code_bucket" { - description = "The GCS bucket code is being stored in for this app." - value = "${module.project-factory.app_engine_code_bucket}" -} - -output "app_engine_default_hostname" { - description = "The default hostname for this app." - value = "${module.project-factory.app_engine_default_hostname}" -} - -output "app_engine_default_bucket" { - description = "The GCS bucket content is being stored in for this app." - value = "${module.project-factory.app_engine_default_bucket}" -} - -output "app_engine_gcr_domain" { - description = "The GCR domain used for storing managed Docker images for this app." - value = "${module.project-factory.app_engine_gcr_domain}" -} diff --git a/modules/gsuite_enabled/variables.tf b/modules/gsuite_enabled/variables.tf index db3bb4c5..a2749086 100644 --- a/modules/gsuite_enabled/variables.tf +++ b/modules/gsuite_enabled/variables.tf @@ -134,28 +134,3 @@ variable "disable_services_on_destroy" { default = "true" type = "string" } - -variable "app_engine_enabled" { - description = "Enable App Engine on the project." - default = false -} - -variable "app_engine_location_id" { - description = "The location to serve the app from." - default = "" -} - -variable "app_engine_auth_domain" { - description = "The domain to authenticate users with when using App Engine's User API." - default = "" -} - -variable "app_engine_serving_status" { - description = "The serving status of the App Engine application." - default = "SERVING" -} - -variable "app_engine_feature_settings" { - description = "A block of optional settings to configure specific App Engine features." - default = [] -} diff --git a/outputs.tf b/outputs.tf index 09cf5903..3e814458 100755 --- a/outputs.tf +++ b/outputs.tf @@ -66,33 +66,3 @@ output "project_bucket_url" { value = "${module.project-factory.project_bucket_url}" description = "Project's bucket url" } - -output "app_engine_name" { - description = "Unique name of the app, usually apps/{PROJECT_ID}." - value = "${module.project-factory.app_engine_name}" -} - -output "app_engine_url_dispatch_rule" { - description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." - value = "${module.project-factory.app_engine_url_dispatch_rule}" -} - -output "app_engine_code_bucket" { - description = "The GCS bucket code is being stored in for this app." - value = "${module.project-factory.app_engine_code_bucket}" -} - -output "app_engine_default_hostname" { - description = "The default hostname for this app." - value = "${module.project-factory.app_engine_default_hostname}" -} - -output "app_engine_default_bucket" { - description = "The GCS bucket content is being stored in for this app." - value = "${module.project-factory.app_engine_default_bucket}" -} - -output "app_engine_gcr_domain" { - description = "The GCR domain used for storing managed Docker images for this app." - value = "${module.project-factory.app_engine_gcr_domain}" -} diff --git a/test/fixtures/full/main.tf b/test/fixtures/full/main.tf index a75da073..6400cf99 100644 --- a/test/fixtures/full/main.tf +++ b/test/fixtures/full/main.tf @@ -104,7 +104,9 @@ module "project-factory" { } module "app-engine" { - project = "${module.project-factory.project_id}" + source = "../../../modules/app_engine" + + project_id = "${module.project-factory.project_id}" location_id = "${var.region}" auth_domain = "${var.domain}" From bf7351868ae390cc76a7845a118b9cac655d84c4 Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Fri, 22 Feb 2019 13:58:19 -0800 Subject: [PATCH 11/13] Fix documentation, remove obsolete variables, and correct outputs --- README.md | 14 ++----------- docs/upgrading_to_project_factory_v2.0.md | 3 +++ examples/app_engine/README.md | 3 ++- examples/gke_shared_vpc/README.md | 3 ++- examples/group_project/README.md | 3 ++- examples/project-hierarchy/README.md | 3 ++- examples/simple_project/README.md | 3 ++- modules/app_engine/outputs.tf | 12 +++++------ modules/core_project_factory/README.md | 14 ++----------- modules/core_project_factory/variables.tf | 25 ----------------------- modules/gsuite_enabled/README.md | 14 ++----------- modules/gsuite_group/README.md | 3 ++- modules/project_services/README.md | 3 ++- test/fixtures/full/README.md | 3 ++- test/fixtures/minimal/README.md | 3 ++- 15 files changed, 33 insertions(+), 76 deletions(-) diff --git a/README.md b/README.md index fdd4e007..017f7455 100644 --- a/README.md +++ b/README.md @@ -89,16 +89,12 @@ The roles granted are specifically: [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | activate_apis | The list of apis to activate within the project | list | `` | no | -| app_engine_auth_domain | The domain to authenticate users with when using App Engine's User API. | string | `` | no | -| app_engine_enabled | Enable App Engine on the project. | string | `false` | no | -| app_engine_feature_settings | A block of optional settings to configure specific App Engine features. | string | `` | no | -| app_engine_location_id | The location to serve the app from. | string | `` | no | -| app_engine_serving_status | The serving status of the App Engine application. | string | `SERVING` | no | | auto_create_network | Create the default network | string | `false` | no | | billing_account | The ID of the billing account to associate this project with | string | - | yes | | bucket_name | A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional) | string | `` | no | @@ -124,12 +120,6 @@ The roles granted are specifically: | Name | Description | |------|-------------| -| app_engine_code_bucket | The GCS bucket code is being stored in for this app. | -| app_engine_default_bucket | The GCS bucket content is being stored in for this app. | -| app_engine_default_hostname | The default hostname for this app. | -| app_engine_gcr_domain | The GCR domain used for storing managed Docker images for this app. | -| app_engine_name | Unique name of the app, usually apps/{PROJECT_ID}. | -| app_engine_url_dispatch_rule | A list of dispatch rule blocks. Each block has a domain, path, and service field. | | domain | The organization's domain | | group_email | The email of the GSuite group with group_name | | project_bucket_self_link | Project's bucket selfLink | @@ -380,4 +370,4 @@ versions][release-new-version]. [terraform-provider-google-beta]: https://github.com/terraform-providers/terraform-provider-google-beta [terraform-provider-gsuite]: https://github.com/DeviaVir/terraform-provider-gsuite [glossary]: /docs/GLOSSARY.md -[release-new-version]: https://www.terraform.io/docs/registry/modules/publish.html#releasing-new-versions +[release-new-version]: https://www.terraform.io/docs/registry/modules/publish.html#releasing-new-versions \ No newline at end of file diff --git a/docs/upgrading_to_project_factory_v2.0.md b/docs/upgrading_to_project_factory_v2.0.md index 5a43b3ea..94bd4962 100644 --- a/docs/upgrading_to_project_factory_v2.0.md +++ b/docs/upgrading_to_project_factory_v2.0.md @@ -36,6 +36,9 @@ The new version of project factory uses a new module named `app_engine`. It acce /// @file main.tf module "app-engine" { + source = "terraform-google-modules/project-factory/google//modules/app_engine" + version = "~> 2.0" + project = "${var.project_id} location_id = "${var.region}" auth_domain = "${var.domain}" diff --git a/examples/app_engine/README.md b/examples/app_engine/README.md index 36d619ba..9c9c17d0 100755 --- a/examples/app_engine/README.md +++ b/examples/app_engine/README.md @@ -14,6 +14,7 @@ Expected variables: [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -30,4 +31,4 @@ Expected variables: | domain_example | The organization's domain | | project_info_example | The ID of the created project | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/examples/gke_shared_vpc/README.md b/examples/gke_shared_vpc/README.md index 465f1237..87ce2c64 100644 --- a/examples/gke_shared_vpc/README.md +++ b/examples/gke_shared_vpc/README.md @@ -25,6 +25,7 @@ More information about GKE with Shared VPC can be found here: https://cloud.goog [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -35,4 +36,4 @@ More information about GKE with Shared VPC can be found here: https://cloud.goog | shared_vpc | The ID of the host project which hosts the shared VPC | string | - | yes | | shared_vpc_subnets | List of subnets fully qualified subnet IDs (ie. projects/$PROJECT_ID/regions/$REGION/subnetworks/$SUBNET_ID) | list | `` | no | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/examples/group_project/README.md b/examples/group_project/README.md index 30fd9c28..d411374c 100644 --- a/examples/group_project/README.md +++ b/examples/group_project/README.md @@ -16,6 +16,7 @@ Expected variables: [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -35,4 +36,4 @@ Expected variables: | group_email_example | The email of the created GSuite group | | project_info_example | The ID of the created project | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/examples/project-hierarchy/README.md b/examples/project-hierarchy/README.md index e2e58501..bb10a55d 100644 --- a/examples/project-hierarchy/README.md +++ b/examples/project-hierarchy/README.md @@ -22,6 +22,7 @@ Expected variables: [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -39,4 +40,4 @@ Expected variables: | project_info_example | The ID of the created prod_gke project | | project_info_factory_example | The ID of the created factory project | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/examples/simple_project/README.md b/examples/simple_project/README.md index a50b8c13..e063001e 100755 --- a/examples/simple_project/README.md +++ b/examples/simple_project/README.md @@ -10,6 +10,7 @@ Expected variables: [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -25,4 +26,4 @@ Expected variables: | domain_example | The organization's domain | | project_info_example | The ID of the created project | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/modules/app_engine/outputs.tf b/modules/app_engine/outputs.tf index 0567c1af..c6764c88 100644 --- a/modules/app_engine/outputs.tf +++ b/modules/app_engine/outputs.tf @@ -16,30 +16,30 @@ output "name" { description = "Unique name of the app, usually apps/{PROJECT_ID}." - value = "${google_app_engine_application.app.0.name}" + value = "${google_app_engine_application.app.name}" } output "url_dispatch_rule" { description = "A list of dispatch rule blocks. Each block has a domain, path, and service field." - value = "${google_app_engine_application.app.0.url_dispatch_rule}" + value = "${google_app_engine_application.app.url_dispatch_rule}" } output "code_bucket" { description = "The GCS bucket code is being stored in for this app." - value = "${google_app_engine_application.app.0.code_bucket}" + value = "${google_app_engine_application.app.code_bucket}" } output "default_hostname" { description = "The default hostname for this app." - value = "${google_app_engine_application.app.0.default_hostname}" + value = "${google_app_engine_application.app.default_hostname}" } output "default_bucket" { description = "The GCS bucket content is being stored in for this app." - value = "${google_app_engine_application.app.0.default_bucket}" + value = "${google_app_engine_application.app.default_bucket}" } output "gcr_domain" { description = "The GCR domain used for storing managed Docker images for this app." - value = "${google_app_engine_application.app.0.gcr_domain}" + value = "${google_app_engine_application.app.gcr_domain}" } diff --git a/modules/core_project_factory/README.md b/modules/core_project_factory/README.md index 5fed6620..3ed76dec 100644 --- a/modules/core_project_factory/README.md +++ b/modules/core_project_factory/README.md @@ -2,16 +2,12 @@ [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | activate_apis | The list of apis to activate within the project | list | `` | no | -| app_engine_auth_domain | The domain to authenticate users with when using App Engine's User API. | string | `` | no | -| app_engine_enabled | Enable App Engine on the project. | string | `false` | no | -| app_engine_feature_settings | A block of optional settings to configure specific App Engine features. | string | `` | no | -| app_engine_location_id | The location to serve the app from. | string | `` | no | -| app_engine_serving_status | The serving status of the App Engine application. | string | `SERVING` | no | | auto_create_network | Create the default network | string | `false` | no | | billing_account | The ID of the billing account to associate this project with | string | - | yes | | bucket_name | A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional) | string | `` | no | @@ -39,12 +35,6 @@ |------|-------------| | api_s_account | API service account email | | api_s_account_fmt | API service account email formatted for terraform use | -| app_engine_code_bucket | The GCS bucket code is being stored in for this app. | -| app_engine_default_bucket | The GCS bucket content is being stored in for this app. | -| app_engine_default_hostname | The default hostname for this app. | -| app_engine_gcr_domain | The GCR domain used for storing managed Docker images for this app. | -| app_engine_name | Unique name of the app, usually apps/{PROJECT_ID}. | -| app_engine_url_dispatch_rule | A list of dispatch rule blocks. Each block has a domain, path, and service field. | | project_bucket_name | The name of the projec's bucket | | project_bucket_self_link | Project's bucket selfLink | | project_bucket_url | Project's bucket url | @@ -56,4 +46,4 @@ | service_account_name | The fully-qualified name of the default service account | | service_account_unique_id | The unique id of the default service account | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/modules/core_project_factory/variables.tf b/modules/core_project_factory/variables.tf index 43561253..1f705d04 100644 --- a/modules/core_project_factory/variables.tf +++ b/modules/core_project_factory/variables.tf @@ -118,28 +118,3 @@ variable "disable_services_on_destroy" { default = "true" type = "string" } - -variable "app_engine_enabled" { - description = "Enable App Engine on the project." - default = false -} - -variable "app_engine_location_id" { - description = "The location to serve the app from." - default = "" -} - -variable "app_engine_auth_domain" { - description = "The domain to authenticate users with when using App Engine's User API." - default = "" -} - -variable "app_engine_serving_status" { - description = "The serving status of the App Engine application." - default = "SERVING" -} - -variable "app_engine_feature_settings" { - description = "A block of optional settings to configure specific App Engine features." - default = [] -} diff --git a/modules/gsuite_enabled/README.md b/modules/gsuite_enabled/README.md index 47d7c8ce..c81f6f7e 100644 --- a/modules/gsuite_enabled/README.md +++ b/modules/gsuite_enabled/README.md @@ -55,17 +55,13 @@ The roles granted are specifically: [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| | activate_apis | The list of apis to activate within the project | list | `` | no | | api_sa_group | A GSuite group to place the Google APIs Service Account for the project in | string | `` | no | -| app_engine_auth_domain | The domain to authenticate users with when using App Engine's User API. | string | `` | no | -| app_engine_enabled | Enable App Engine on the project. | string | `false` | no | -| app_engine_feature_settings | A block of optional settings to configure specific App Engine features. | string | `` | no | -| app_engine_location_id | The location to serve the app from. | string | `` | no | -| app_engine_serving_status | The serving status of the App Engine application. | string | `SERVING` | no | | auto_create_network | Create the default network | string | `false` | no | | billing_account | The ID of the billing account to associate this project with | string | - | yes | | bucket_name | A name for a GCS bucket to create (in the bucket_project project), useful for Terraform state (optional) | string | `` | no | @@ -93,12 +89,6 @@ The roles granted are specifically: | Name | Description | |------|-------------| -| app_engine_code_bucket | The GCS bucket code is being stored in for this app. | -| app_engine_default_bucket | The GCS bucket content is being stored in for this app. | -| app_engine_default_hostname | The default hostname for this app. | -| app_engine_gcr_domain | The GCR domain used for storing managed Docker images for this app. | -| app_engine_name | Unique name of the app, usually apps/{PROJECT_ID}. | -| app_engine_url_dispatch_rule | A list of dispatch rule blocks. Each block has a domain, path, and service field. | | domain | The organization's domain | | group_email | The email of the created GSuite group with group_name | | project_bucket_self_link | Project's bucket selfLink | @@ -114,4 +104,4 @@ The roles granted are specifically: [^]: (autogen_docs_end) [examples]: ../../examples/ -[root-module]: ../../README.md +[root-module]: ../../README.md \ No newline at end of file diff --git a/modules/gsuite_group/README.md b/modules/gsuite_group/README.md index aca1e361..c6812208 100644 --- a/modules/gsuite_group/README.md +++ b/modules/gsuite_group/README.md @@ -2,6 +2,7 @@ [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -18,4 +19,4 @@ | domain | The domain of the group's organization. | | email | The email address of the group. | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/modules/project_services/README.md b/modules/project_services/README.md index f4a7ecb6..c05e5dea 100644 --- a/modules/project_services/README.md +++ b/modules/project_services/README.md @@ -23,6 +23,7 @@ See [examples/project_services](./examples/project_services) for an example. [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -38,4 +39,4 @@ See [examples/project_services](./examples/project_services) for an example. |------|-------------| | project_id | The GCP project you want to enable APIs on | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/test/fixtures/full/README.md b/test/fixtures/full/README.md index 9086d500..b1385c0e 100644 --- a/test/fixtures/full/README.md +++ b/test/fixtures/full/README.md @@ -2,6 +2,7 @@ [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -41,4 +42,4 @@ | usage_bucket_name | | | usage_bucket_prefix | | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file diff --git a/test/fixtures/minimal/README.md b/test/fixtures/minimal/README.md index ca17d297..df0ea00b 100644 --- a/test/fixtures/minimal/README.md +++ b/test/fixtures/minimal/README.md @@ -2,6 +2,7 @@ [^]: (autogen_docs_start) + ## Inputs | Name | Description | Type | Default | Required | @@ -40,4 +41,4 @@ | usage_bucket_name | | | usage_bucket_prefix | | -[^]: (autogen_docs_end) +[^]: (autogen_docs_end) \ No newline at end of file From d92e749f5fb8120c82dc4adb77015bd1b76e2713 Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Mon, 25 Feb 2019 12:22:06 -0800 Subject: [PATCH 12/13] Update README for fixed g suite group module --- modules/gsuite_group/README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/gsuite_group/README.md b/modules/gsuite_group/README.md index c6812208..7fbd4c03 100644 --- a/modules/gsuite_group/README.md +++ b/modules/gsuite_group/README.md @@ -7,7 +7,6 @@ | Name | Description | Type | Default | Required | |------|-------------|:----:|:-----:|:-----:| -| create_group | Whether to create the group or not | string | `false` | no | | domain | The domain name | string | `` | no | | name | The name of the group. | string | - | yes | | org_id | The organization ID. | string | - | yes | From 37572d05d91da39413b52e4cc5efc5cc5147355a Mon Sep 17 00:00:00 2001 From: Danny Seymour Date: Tue, 19 Feb 2019 11:33:46 -0800 Subject: [PATCH 13/13] Add unit test to check G Suite group is created Fixes https://github.com/terraform-google-modules/terraform-google-project-factory/issues/111 --- modules/core_project_factory/main.tf | 2 +- test/fixtures/full/main.tf | 14 +++--- test/integration/full/controls/gsuite.rb | 6 +++ test/scripts/gsuite/gsuite_groups.py | 63 ++++++++++++++++++++++++ 4 files changed, 78 insertions(+), 7 deletions(-) create mode 100755 test/scripts/gsuite/gsuite_groups.py diff --git a/modules/core_project_factory/main.tf b/modules/core_project_factory/main.tf index 61586fb6..2f042bac 100644 --- a/modules/core_project_factory/main.tf +++ b/modules/core_project_factory/main.tf @@ -128,7 +128,7 @@ resource "google_compute_shared_vpc_service_project" "shared_vpc_attachment" { Default compute service account retrieval *****************************************/ data "google_compute_default_service_account" "default" { - project = "${google_project.main.id}" + project = "${google_project.main.project_id}" depends_on = ["google_project_service.project_services"] } diff --git a/test/fixtures/full/main.tf b/test/fixtures/full/main.tf index 6400cf99..79a211b4 100644 --- a/test/fixtures/full/main.tf +++ b/test/fixtures/full/main.tf @@ -50,7 +50,8 @@ module "vpc" { source = "terraform-google-modules/network/google" version = "~> 0.4.0" network_name = "pf-test-int-full-${random_string.suffix.result}" - project_id = "${var.shared_vpc}" + + project_id = "${var.shared_vpc}" # The provided project must already be a Shared VPC host shared_vpc_host = "false" @@ -89,11 +90,12 @@ module "project-factory" { group_role = "${var.group_role}" group_name = "${var.group_name}" shared_vpc = "${var.shared_vpc}" - shared_vpc_subnets = "${local.shared_vpc_subnets}" - sa_role = "${var.sa_role}" - sa_group = "${var.sa_group}" - credentials_path = "${var.credentials_path}" - lien = "true" + + shared_vpc_subnets = "${local.shared_vpc_subnets}" + sa_role = "${var.sa_role}" + sa_group = "${var.sa_group}" + credentials_path = "${var.credentials_path}" + lien = "true" activate_apis = [ "compute.googleapis.com", diff --git a/test/integration/full/controls/gsuite.rb b/test/integration/full/controls/gsuite.rb index d8c53757..bfe0e699 100644 --- a/test/integration/full/controls/gsuite.rb +++ b/test/integration/full/controls/gsuite.rb @@ -18,6 +18,7 @@ project_id = attribute('project_id') service_account_email = attribute('service_account_email') credentials_path = attribute('credentials_path') +gsuite_admin_account = attribute('gsuite_admin_account') ENV['CLOUDSDK_AUTH_CREDENTIAL_FILE_OVERRIDE'] = File.absolute_path( credentials_path, @@ -74,4 +75,9 @@ ) end end + + describe command("./test/scripts/gsuite/gsuite_groups.py --sa-json-credentials=#{credentials_path} --group-email #{group_email} --impersonate-user #{gsuite_admin_account}") do + its('exit_status') { should eq 0 } + its('stderr') { should eq '' } + end end diff --git a/test/scripts/gsuite/gsuite_groups.py b/test/scripts/gsuite/gsuite_groups.py new file mode 100755 index 00000000..05bf2181 --- /dev/null +++ b/test/scripts/gsuite/gsuite_groups.py @@ -0,0 +1,63 @@ +#! /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 argparse +from googleapiclient.errors import HttpError +from googleapiclient.discovery import build +from google.oauth2 import service_account + +SCOPES = ['https://www.googleapis.com/auth/admin.directory.group'] + + +def authenticate(impersonated_user, sa_json_file_path, scopes): + print('Getting delegated credentials for %s' % impersonated_user) + + return service_account.Credentials.from_service_account_file( + sa_json_file_path, + scopes=scopes, + subject=impersonated_user + ) + + + +def group_exists(service, group_email): + try: + return service.groups().get(groupKey=group_email).execute() + except HttpError as e: + if e.resp.status == 404: + print('Group %s does not exist' % group_email) + exit(1) + else: + print('Error fetching groups %s %s' % e.content, e.error_details) + exit(2) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description='Test if the specified G Suite exists') + parser.add_argument('--sa-json-credentials', dest='sa_json_credentials') + parser.add_argument('--group-email', dest='group_email') + parser.add_argument('--impersonate-user', dest='impersonate_user') + args = parser.parse_args() + + service = build("admin", + "directory_v1", + credentials=authenticate( + args.impersonate_user, + args.sa_json_credentials, + SCOPES) + ) + group_exists(service, args.group_email)