Skip to content

Commit

Permalink
feat!: use remote state to read data from previous steps (#782)
Browse files Browse the repository at this point in the history
* add output for remote state information

* use remote state in step 1-org

* fix integration test

* use remote state date in step 5

* fix disable script

* add force destroy on bootstrap

* update outputs for step 1-org

* update tests

* add remote state to step 2-envs

* move backend initialization to the end of apply phase

* user remote state in step 4-projects

* add remote state to 3-networks-dual-svpc

* add remote state to 3-networks-hub-and-spoke

* update test to use remote state in step 3-networks

* fix bootstrap apply stage in integration test

* fix soft link cyclo

* update script to disable tf files

* fix step 5-app-infra test

* remove extra vars from test initialization

* remove terraform service account from the var in step 4 integration test

* remove project service account from test vars

* split projects test into test for shared and test for envs

* fix READMEs and tfvars files

* restore 5-app-infra

* remove remote_state.tf file

* fix null provider version

* restore gcloud beta terraform vet info

* remove interpolation from backend_bucket usage

* organize remote state values

* add explanation of usage of remote state output values

Co-authored-by: Bharath KKB <bharathkrishnakb@gmail.com>
  • Loading branch information
daniel-cit and bharathkkb authored Sep 1, 2022
1 parent f35dcc5 commit a761a99
Show file tree
Hide file tree
Showing 203 changed files with 1,474 additions and 2,142 deletions.
1 change: 1 addition & 0 deletions 0-bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ the following steps:
| Name | Description |
|------|-------------|
| cloudbuild\_project\_id | Project where CloudBuild configuration and terraform container image will reside. |
| common\_config | Common configuration data to be used in other steps. |
| csr\_repos | List of Cloud Source Repos created by the module, linked to Cloud Build triggers. |
| environment\_step\_terraform\_service\_account\_email | Environment Step Terraform Account |
| gcs\_bucket\_cloudbuild\_artifacts | Bucket used to store Cloud/Build artifacts in CloudBuild project. |
Expand Down
17 changes: 13 additions & 4 deletions 0-bootstrap/modules/parent-iam-member/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,31 @@
*/

locals {
org_id = var.parent_type == "organization" ? var.parent_id : ""
folder_id = var.parent_type == "folder" ? var.parent_id : ""
org_id = var.parent_type == "organization" ? var.parent_id : ""
folder_id = var.parent_type == "folder" ? var.parent_id : ""
project_id = var.parent_type == "project" ? var.parent_id : ""
}

resource "google_organization_iam_member" "org_parent_iam" {
for_each = toset(local.org_id != "" ? var.roles : [])
for_each = toset(var.parent_type == "organization" ? var.roles : [])

org_id = local.org_id
role = each.key
member = var.member
}

resource "google_folder_iam_member" "folder_parent_iam" {
for_each = toset(local.folder_id != "" ? var.roles : [])
for_each = toset(var.parent_type == "folder" ? var.roles : [])

folder = local.folder_id
role = each.key
member = var.member
}

resource "google_project_iam_member" "project_parent_iam" {
for_each = toset(var.parent_type == "project" ? var.roles : [])

project = local.project_id
role = each.key
member = var.member
}
6 changes: 3 additions & 3 deletions 0-bootstrap/modules/parent-iam-member/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
*/

variable "parent_type" {
description = "Type of the parent resource. valid values are `organization` and `folder`."
description = "Type of the parent resource. valid values are `organization`, `folder`, and `project`."
type = string

validation {
condition = var.parent_type == "organization" || var.parent_type == "folder"
error_message = "For parent_type only `organization` and `folder` are valid."
condition = var.parent_type == "organization" || var.parent_type == "folder" || var.parent_type == "project"
error_message = "For parent_type only `organization`, `folder`, and `project` are valid."
}
}

Expand Down
14 changes: 14 additions & 0 deletions 0-bootstrap/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ output "gcs_bucket_tfstate" {
value = module.seed_bootstrap.gcs_bucket_tfstate
}

output "common_config" {
description = "Common configuration data to be used in other steps."
value = {
org_id = var.org_id,
parent_folder = var.parent_folder,
billing_account = var.billing_account,
default_region = var.default_region,
project_prefix = var.project_prefix,
folder_prefix = var.folder_prefix
parent_id = local.parent
bootstrap_folder_name = google_folder.bootstrap.name
}
}

/* ----------------------------------------
Specific to cloudbuild_module
---------------------------------------- */
Expand Down
25 changes: 25 additions & 0 deletions 0-bootstrap/sa.tf
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,21 @@ locals {
"roles/compute.xpnAdmin",
],
}

granular_sa_seed_project = {
"org" = [
"roles/storage.objectAdmin",
],
"env" = [
"roles/storage.objectAdmin"
],
"net" = [
"roles/storage.objectAdmin",
],
"proj" = [
"roles/storage.objectAdmin",
],
}
}

resource "google_service_account" "terraform-env-sa" {
Expand Down Expand Up @@ -97,6 +112,16 @@ module "parent_iam_member" {
roles = each.value
}

module "project_iam_member" {
source = "./modules/parent-iam-member"
for_each = local.granular_sa_seed_project

member = "serviceAccount:${google_service_account.terraform-env-sa[each.key].email}"
parent_type = "project"
parent_id = module.seed_bootstrap.seed_project_id
roles = each.value
}

resource "google_billing_account_iam_member" "tf_billing_user" {
for_each = local.granular_sa

Expand Down
8 changes: 2 additions & 6 deletions 1-org/envs/shared/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,19 @@
| audit\_data\_users | Google Workspace or Cloud Identity group that have access to audit logs. | `string` | n/a | yes |
| audit\_logs\_table\_delete\_contents\_on\_destroy | (Optional) If set to true, delete all the tables in the dataset when destroying the resource; otherwise, destroying the resource will fail if tables are present. | `bool` | `false` | no |
| audit\_logs\_table\_expiration\_days | Period before tables expire for all audit logs in milliseconds. Default is 30 days. | `number` | `30` | no |
| backend\_bucket | Backend bucket to load remote state information from previous steps. | `string` | n/a | yes |
| base\_net\_hub\_project\_alert\_pubsub\_topic | The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}` for the base net hub project. | `string` | `null` | no |
| base\_net\_hub\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the base net hub project. | `list(number)` | <pre>[<br> 0.5,<br> 0.75,<br> 0.9,<br> 0.95<br>]</pre> | no |
| base\_net\_hub\_project\_budget\_amount | The amount to use as the budget for the base net hub project. | `number` | `1000` | no |
| billing\_account | The ID of the billing account to associate this project with | `string` | n/a | yes |
| billing\_data\_users | Google Workspace or Cloud Identity group that have access to billing data set. | `string` | n/a | yes |
| create\_access\_context\_manager\_access\_policy | Whether to create access context manager access policy | `bool` | `true` | no |
| data\_access\_logs\_enabled | Enable Data Access logs of types DATA\_READ, DATA\_WRITE for all GCP services. Enabling Data Access logs might result in your organization being charged for the additional logs usage. See https://cloud.google.com/logging/docs/audit#data-access The ADMIN\_READ logs are enabled by default. | `bool` | `false` | no |
| default\_region | Default region for BigQuery resources. | `string` | n/a | yes |
| dns\_hub\_project\_alert\_pubsub\_topic | The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}` for the DNS hub project. | `string` | `null` | no |
| dns\_hub\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the DNS hub project. | `list(number)` | <pre>[<br> 0.5,<br> 0.75,<br> 0.9,<br> 0.95<br>]</pre> | no |
| dns\_hub\_project\_budget\_amount | The amount to use as the budget for the DNS hub project. | `number` | `1000` | no |
| domains\_to\_allow | The list of domains to allow users from in IAM. Used by Domain Restricted Sharing Organization Policy. Must include the domain of the organization you are deploying the foundation. To add other domains you must also grant access to these domains to the terraform service account used in the deploy. | `list(string)` | n/a | yes |
| enable\_hub\_and\_spoke | Enable Hub-and-Spoke architecture. | `bool` | `false` | no |
| enable\_os\_login\_policy | Enable OS Login Organization Policy. | `bool` | `false` | no |
| folder\_prefix | Name prefix to use for folders created. Should be the same in all steps. | `string` | `"fldr"` | no |
| gcp\_audit\_viewer | Members are part of an audit team and view audit logs in the logging project. | `string` | `null` | no |
| gcp\_billing\_admin\_user | Identity that has billing administrator permissions | `string` | `null` | no |
| gcp\_billing\_creator\_user | Identity that can create billing accounts. | `string` | `null` | no |
Expand All @@ -44,12 +42,9 @@
| org\_billing\_logs\_project\_alert\_pubsub\_topic | The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}` for the org billing logs project. | `string` | `null` | no |
| org\_billing\_logs\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the org billing logs project. | `list(number)` | <pre>[<br> 0.5,<br> 0.75,<br> 0.9,<br> 0.95<br>]</pre> | no |
| org\_billing\_logs\_project\_budget\_amount | The amount to use as the budget for the org billing logs project. | `number` | `1000` | no |
| org\_id | The organization id for the associated services | `string` | n/a | yes |
| org\_secrets\_project\_alert\_pubsub\_topic | The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}` for the org secrets project. | `string` | `null` | no |
| org\_secrets\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the org secrets project. | `list(number)` | <pre>[<br> 0.5,<br> 0.75,<br> 0.9,<br> 0.95<br>]</pre> | no |
| org\_secrets\_project\_budget\_amount | The amount to use as the budget for the org secrets project. | `number` | `1000` | no |
| parent\_folder | Optional - for an organization with existing projects or for development/validation. It will place all the example foundation resources under the provided folder instead of the root organization. The value is the numeric folder ID. The folder must already exist. Must be the same value used in previous step. | `string` | `""` | no |
| project\_prefix | Name prefix to use for projects created. Should be the same in all steps. Max size is 3 characters. | `string` | `"prj"` | no |
| restricted\_net\_hub\_project\_alert\_pubsub\_topic | The name of the Cloud Pub/Sub topic where budget related messages will be published, in the form of `projects/{project_id}/topics/{topic_id}` for the restricted net hub project. | `string` | `null` | no |
| restricted\_net\_hub\_project\_alert\_spent\_percents | A list of percentages of the budget to alert on when threshold is exceeded for the restricted net hub project. | `list(number)` | <pre>[<br> 0.5,<br> 0.75,<br> 0.9,<br> 0.95<br>]</pre> | no |
| restricted\_net\_hub\_project\_budget\_amount | The amount to use as the budget for the restricted net hub project. | `number` | `1000` | no |
Expand Down Expand Up @@ -78,6 +73,7 @@
| parent\_resource\_id | The parent resource id |
| parent\_resource\_type | The parent resource type |
| restricted\_net\_hub\_project\_id | The Restricted Network hub project ID |
| restricted\_net\_hub\_project\_number | The Restricted Network hub project number |
| scc\_notification\_name | Name of SCC Notification |
| scc\_notifications\_project\_id | The SCC notifications project ID |

Expand Down
6 changes: 1 addition & 5 deletions 1-org/envs/shared/folders.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@
* limitations under the License.
*/

locals {
parent = var.parent_folder != "" ? "folders/${var.parent_folder}" : "organizations/${var.org_id}"
}

/******************************************
Top level folders
*****************************************/

resource "google_folder" "common" {
display_name = "${var.folder_prefix}-common"
display_name = "${local.folder_prefix}-common"
parent = local.parent
}
48 changes: 24 additions & 24 deletions 1-org/envs/shared/iam.tf
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ locals {
}

resource "google_organization_iam_audit_config" "org_config" {
count = var.parent_folder == "" ? 1 : 0
org_id = var.org_id
count = local.parent_folder == "" ? 1 : 0
org_id = local.org_id
service = "allServices"

###################################################################################################
Expand All @@ -44,8 +44,8 @@ resource "google_organization_iam_audit_config" "org_config" {
}

resource "google_folder_iam_audit_config" "folder_config" {
count = var.parent_folder != "" ? 1 : 0
folder = "folders/${var.parent_folder}"
count = local.parent_folder != "" ? 1 : 0
folder = "folders/${local.parent_folder}"
service = "allServices"

###################################################################################################
Expand Down Expand Up @@ -97,7 +97,7 @@ resource "google_project_iam_member" "billing_bq_viewer" {
*****************************************/

resource "google_organization_iam_member" "billing_viewer" {
org_id = var.org_id
org_id = local.org_id
role = "roles/billing.viewer"
member = "group:${var.billing_data_users}"
}
Expand All @@ -107,43 +107,43 @@ resource "google_organization_iam_member" "billing_viewer" {
*****************************************/

resource "google_organization_iam_member" "organization_viewer" {
count = var.gcp_platform_viewer != null && var.parent_folder == "" ? 1 : 0
org_id = var.org_id
count = var.gcp_platform_viewer != null && local.parent_folder == "" ? 1 : 0
org_id = local.org_id
role = "roles/viewer"
member = "group:${var.gcp_platform_viewer}"
}

resource "google_folder_iam_member" "organization_viewer" {
count = var.gcp_platform_viewer != null && var.parent_folder != "" ? 1 : 0
folder = "folders/${var.parent_folder}"
count = var.gcp_platform_viewer != null && local.parent_folder != "" ? 1 : 0
folder = "folders/${local.parent_folder}"
role = "roles/viewer"
member = "group:${var.gcp_platform_viewer}"
}

resource "google_organization_iam_member" "security_reviewer" {
count = var.gcp_security_reviewer != null && var.parent_folder == "" ? 1 : 0
org_id = var.org_id
count = var.gcp_security_reviewer != null && local.parent_folder == "" ? 1 : 0
org_id = local.org_id
role = "roles/iam.securityReviewer"
member = "group:${var.gcp_security_reviewer}"
}

resource "google_folder_iam_member" "security_reviewer" {
count = var.gcp_security_reviewer != null && var.parent_folder != "" ? 1 : 0
folder = "folders/${var.parent_folder}"
count = var.gcp_security_reviewer != null && local.parent_folder != "" ? 1 : 0
folder = "folders/${local.parent_folder}"
role = "roles/iam.securityReviewer"
member = "group:${var.gcp_security_reviewer}"
}

resource "google_organization_iam_member" "network_viewer" {
count = var.gcp_network_viewer != null && var.parent_folder == "" ? 1 : 0
org_id = var.org_id
count = var.gcp_network_viewer != null && local.parent_folder == "" ? 1 : 0
org_id = local.org_id
role = "roles/compute.networkViewer"
member = "group:${var.gcp_network_viewer}"
}

resource "google_folder_iam_member" "network_viewer" {
count = var.gcp_network_viewer != null && var.parent_folder != "" ? 1 : 0
folder = "folders/${var.parent_folder}"
count = var.gcp_network_viewer != null && local.parent_folder != "" ? 1 : 0
folder = "folders/${local.parent_folder}"
role = "roles/compute.networkViewer"
member = "group:${var.gcp_network_viewer}"
}
Expand Down Expand Up @@ -188,29 +188,29 @@ resource "google_project_iam_member" "global_secrets_admin" {
*****************************************/

resource "google_organization_iam_member" "org_admin_user" {
count = var.gcp_org_admin_user != null && var.parent_folder == "" ? 1 : 0
org_id = var.org_id
count = var.gcp_org_admin_user != null && local.parent_folder == "" ? 1 : 0
org_id = local.org_id
role = "roles/resourcemanager.organizationAdmin"
member = "user:${var.gcp_org_admin_user}"
}

resource "google_folder_iam_member" "org_admin_user" {
count = var.gcp_org_admin_user != null && var.parent_folder != "" ? 1 : 0
folder = "folders/${var.parent_folder}"
count = var.gcp_org_admin_user != null && local.parent_folder != "" ? 1 : 0
folder = "folders/${local.parent_folder}"
role = "roles/resourcemanager.folderAdmin"
member = "user:${var.gcp_org_admin_user}"
}

resource "google_organization_iam_member" "billing_creator_user" {
count = var.gcp_billing_creator_user != null && var.parent_folder == "" ? 1 : 0
org_id = var.org_id
count = var.gcp_billing_creator_user != null && local.parent_folder == "" ? 1 : 0
org_id = local.org_id
role = "roles/billing.creator"
member = "user:${var.gcp_billing_creator_user}"
}

resource "google_billing_account_iam_member" "billing_admin_user" {
count = var.gcp_billing_admin_user != null ? 1 : 0
billing_account_id = var.billing_account
billing_account_id = local.billing_account
role = "roles/billing.admin"
member = "user:${var.gcp_billing_admin_user}"
}
6 changes: 3 additions & 3 deletions 1-org/envs/shared/log_sinks.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
*/

locals {
parent_resource_id = var.parent_folder != "" ? var.parent_folder : var.org_id
parent_resource_type = var.parent_folder != "" ? "folder" : "organization"
parent_resource_id = local.parent_folder != "" ? local.parent_folder : local.org_id
parent_resource_type = local.parent_folder != "" ? "folder" : "organization"
main_logs_filter = <<EOF
logName: /logs/cloudaudit.googleapis.com%2Factivity OR
logName: /logs/cloudaudit.googleapis.com%2Fsystem_event OR
Expand Down Expand Up @@ -125,5 +125,5 @@ resource "google_bigquery_dataset" "billing_dataset" {
dataset_id = "billing_data"
project = module.org_billing_logs.project_id
friendly_name = "GCP Billing Data"
location = var.default_region
location = local.default_region
}
38 changes: 38 additions & 0 deletions 1-org/envs/shared/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2022 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.
*/

// These values are retrieved from the saved terraform state of the execution
// of step 0-bootstrap using the terraform_remote_state data source.
// These values can be overridden here if needed.
// Some values, like org_id, parent_folder, and parent, must be consistent in all steps.
locals {
org_id = data.terraform_remote_state.bootstrap.outputs.common_config.org_id
parent_folder = data.terraform_remote_state.bootstrap.outputs.common_config.parent_folder
parent = data.terraform_remote_state.bootstrap.outputs.common_config.parent_id
billing_account = data.terraform_remote_state.bootstrap.outputs.common_config.billing_account
default_region = data.terraform_remote_state.bootstrap.outputs.common_config.default_region
project_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.project_prefix
folder_prefix = data.terraform_remote_state.bootstrap.outputs.common_config.folder_prefix
}

data "terraform_remote_state" "bootstrap" {
backend = "gcs"

config = {
bucket = var.backend_bucket
prefix = "terraform/bootstrap/state"
}
}
8 changes: 4 additions & 4 deletions 1-org/envs/shared/org_policy.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
*/

locals {
organization_id = var.parent_folder != "" ? null : var.org_id
folder_id = var.parent_folder != "" ? var.parent_folder : null
policy_for = var.parent_folder != "" ? "folder" : "organization"
organization_id = local.parent_folder != "" ? null : local.org_id
folder_id = local.parent_folder != "" ? local.parent_folder : null
policy_for = local.parent_folder != "" ? "folder" : "organization"
}


Expand Down Expand Up @@ -174,6 +174,6 @@ module "org_enforce_bucket_level_access" {

resource "google_access_context_manager_access_policy" "access_policy" {
count = var.create_access_context_manager_access_policy ? 1 : 0
parent = "organizations/${var.org_id}"
parent = "organizations/${local.org_id}"
title = "default policy"
}
Loading

0 comments on commit a761a99

Please sign in to comment.