Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Averbuks org business units #3

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
83b2c12
add gitignore file
ludoo Aug 10, 2019
315e307
data and infra skeletons
ludoo Aug 10, 2019
4d4c618
org skeleton
ludoo Aug 10, 2019
5f013bf
org environments sample skeleton
ludoo Aug 10, 2019
820fe12
Organization teams sample skeleton.
ludoo Aug 11, 2019
0f523cd
Organization env sample GCS for tf state.
ludoo Aug 11, 2019
b70f2ad
org env: service accounts and GCS roles
ludoo Aug 12, 2019
79bcf56
org env: folders
ludoo Aug 12, 2019
6ad6936
org env: audit export
ludoo Aug 12, 2019
79f45d9
org env: shared project
ludoo Aug 12, 2019
8c6b46f
org env: switch to released 3.1.0 project module version
ludoo Aug 12, 2019
8fbeebf
rename organization top-level folder to organization-bootstrap
ludoo Aug 12, 2019
e381d4d
org env: use folders module with better outputs, module outputs
ludoo Aug 12, 2019
ba70fb2
org env: switch the service accounts module to v2.0.0.
ludoo Aug 15, 2019
7b9d1fe
Merge ludo's branch from forked repo (#2)
ludoo Aug 19, 2019
e0826a7
org env: update folders module version, improve comments
ludoo Aug 19, 2019
7fcc20f
org env: initial work on README, diagram, add variable for xpn roles
ludoo Aug 20, 2019
23e86e4
org env: update roles in README, backend file
ludoo Aug 20, 2019
70adb1e
org env: README changes
ludoo Aug 21, 2019
956a868
org env: README changes
ludoo Aug 21, 2019
ee81ce4
org env: README changes
ludoo Aug 21, 2019
e3b4cb9
org env: README changes
ludoo Aug 21, 2019
95408f5
org env: add IAM variables for audit and shared projects
ludoo Aug 21, 2019
4e7ffe4
Business-units organization bootstrap example, initial commit
averbuks Aug 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
**/.terraform
**/terraform.tfstate*
**/terraform.tfvars
.idea
.vscode
backend-config.hcl
credentials.json
key.json
Empty file added data/README.md
Empty file.
Empty file added infrastructure/README.md
Empty file.
Empty file.
102 changes: 102 additions & 0 deletions organization-bootstrap/business-units/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Business-units based organizational sample

This sample creates an organizational layout with two folder levels, where the first level is usually mapped to one business unit (infra, data, analythics) and the second level represents enviroments (prod, test). It also sets up all prerequisites for automation (GCS state buckets, service accounts, etc.), and the correct roles on those to enforce separation of duties at the environment level.

This layout is well suited for small and medium-sized infrastructures managed by a smal set of teams, where the complexity in application resource ownership and access roles is mostly dealt with at the project level, and/or in the individual services (GKE, Cloud SQL, etc.). Its simplicity also makes it a good starting point for more complex or specialized layouts.

This layout is well suited for medium-sized infrastructures managed by different sets of teams grouped to different business units, where the complexity in application resource ownership and access roles is mostly dealt with at the project level, and/or in the individual services (GKE, Cloud SQL, etc.).

![High-level diagram](diagram.png "High-level diagram")

This set of Terraform files is usually applied manually by an org-level administrator as a first step, and then reapplied only when a new business-unit or environment needs to be created or an existing one removed, and serves different purposes:

- automating and parameterizing creation of the organizational layout
- automating creation of the base resources needed for Terraform automation, obviating the need for external scripts or hand-coded commands
- anticipating the requirement of organizational-level roles for specific resources (eg Shared VPC), by granting them to the service accounts used for environment automation
- enforcing separation of duties by using separate sets of automation resources (GCS, service accounts) for each environment, and only granting roles scoped to the environment's folder

## Managed resources and services

This sample creates several distinct groups of resources:

- one folder per business unit
- two second-level folders (test, prod) for every business unit
- one top-level project to hold Terraform-related resources
- one top-level project to set up and host centralized audit log exports (optional).
- one top-level project to hold services used across environments like GCS, GCR, KMS, Cloud Build, etc. (optional)

The number of resources in this sample is kept to a minimum so as to make it generally applicable, more resources can be easily added by leveraging the full array of [Cloud Foundation Toolkit modules](https://github.com/terraform-google-modules), especially in the shared services project.

## Operational considerations

As mentioned above this root module is meant to be run infrequently, only when an environment or a shared service needs to be added or changed, so the advantages of automating it in a CI pipeline are very limited.

### IAM roles

Regardless of how it's run, the credentials used need very specific roles on the root node, plus additional roles at the organization level if Shared VPC usage is anticipated in environments:

- Billing Account Administrator on the billing account or organization
- Folder Administrator
- Logging Administrator on the root folder or organization
- Project Creator
- Organization Administrator, if Shared VPC roles need to be granted

### State

TODO: describe the state switch that needs to be done after first apply

### Things to be aware of

TODO: describe potential issues with multiple resources, and the upcoming `foreach` fix
TODO: describe how `prefix` can be used to enforce naming
TODO: describe xpn roles

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| audit\_viewers | Audit project viewers, in IAM format. | list | `<list>` | no |
| billing\_account\_id | Billing account id used as default for new projects. | string | n/a | yes |
| business\_unit\_1\_envs | Business unit 1 environments short names. | list(string) | `<list>` | no |
| business\_unit\_1\_name | Business unit 1 short name. | string | n/a | yes |
| business\_unit\_2\_envs | Business unit 2 environments short names. | list(string) | `<list>` | no |
| business\_unit\_2\_name | Business unit 2 short name. | string | n/a | yes |
| business\_unit\_3\_envs | Business unit 3 environments short names. | list(string) | `<list>` | no |
| business\_unit\_3\_name | Business unit 3 short name. | string | n/a | yes |
| gcs\_location | GCS bucket location. | string | `"EU"` | no |
| generate\_service\_account\_keys | Generate and store service account keys in the state file. | string | `"false"` | no |
| organization\_id | Organization id. | string | n/a | yes |
| prefix | Prefix used for resources that need unique names. | string | n/a | yes |
| project\_services | Service APIs enabled by default in new projects. | list | `<list>` | no |
| root\_node | Root node for the new hierarchy, either 'organizations/org_id' or 'folders/folder_id'. | string | n/a | yes |
| shared\_bindings\_members | List of comma-delimited IAM-format members for the additional shared project bindings. | list | `<list>` | no |
| shared\_bindings\_roles | List of roles for additional shared project bindings. | list | `<list>` | no |
| terraform\_owners | Terraform project owners, in IAM format. | list | `<list>` | no |

## Outputs

| Name | Description |
|------|-------------|
| audit\_logs\_bq\_dataset | Bigquery dataset for the audit logs export. |
| audit\_logs\_project | Project that holds the audit logs export resources. |
| bootstrap\_tf\_gcs\_bucket | GCS bucket used for the bootstrap Terraform state. |
| business\_unit\_1\_envs\_folders\_ids | Business unit 1 environment folders. |
| business\_unit\_1\_envs\_service\_account\_keys | Service account keys used to run each environment Terraform modules for business unit 1. |
| business\_unit\_1\_envs\_service\_accounts | Service accounts used to run each environment Terraform modules for business unit 1. |
| business\_unit\_1\_envs\_tf\_gcs\_buckets | GCS buckets used for each environment Terraform state for business unit 1. |
| business\_unit\_1\_top\_level\_folder\_id | Business unit 1 top-level folder. |
| business\_unit\_2\_envs\_folders\_ids | Business unit 2 environment folders. |
| business\_unit\_2\_envs\_service\_account\_keys | Service account keys used to run each environment Terraform modules for business unit 2. |
| business\_unit\_2\_envs\_service\_accounts | Service accounts used to run each environment Terraform modules for business unit 2. |
| business\_unit\_2\_envs\_tf\_gcs\_buckets | GCS buckets used for each environment Terraform state for business unit 2. |
| business\_unit\_2\_top\_level\_folder\_id | Business unit 2 top-level folder. |
| business\_unit\_3\_envs\_folders\_ids | Business unit 3 environment folders. |
| business\_unit\_3\_envs\_service\_account\_keys | Service account keys used to run each environment Terraform modules for business unit 3. |
| business\_unit\_3\_envs\_service\_accounts | Service accounts used to run each environment Terraform modules for business unit 3. |
| business\_unit\_3\_envs\_tf\_gcs\_buckets | GCS buckets used for each environment Terraform state for business unit 3. |
| business\_unit\_3\_top\_level\_folder\_id | Business unit 3 top-level folder. |
| shared\_resources\_project | Project that holdes resources shared across business units. |
| terraform\_project | Project that holds the base Terraform resources. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
21 changes: 21 additions & 0 deletions organization-bootstrap/business-units/backend.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# 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
#
# 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.

# comment before initial run

terraform {
backend "gcs" {
bucket = ""
}
}
Binary file added organization-bootstrap/business-units/diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
162 changes: 162 additions & 0 deletions organization-bootstrap/business-units/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# 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
#
# 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.

###############################################################################
# Terraform top-level resources #
###############################################################################

# Terraform project

module "project-tf" {
source = "terraform-google-modules/project-factory/google//modules/fabric-project"
version = "3.2.0"
parent = var.root_node
billing_account = var.billing_account_id
prefix = var.prefix
name = "terraform"
lien_reason = "terraform"
owners = var.terraform_owners
activate_apis = var.project_services
}

# Bootstrap Terraform state GCS bucket

module "gcs-tf-bootstrap" {
source = "terraform-google-modules/cloud-storage/google"
version = "1.0.0"
project_id = module.project-tf.project_id
prefix = "${var.prefix}-tf"
names = ["tf-bootstrap"]
location = var.gcs_location
}

###############################################################################
# Business units #
###############################################################################

# Business unit 1

module "business-unit-1-folders-tree" {
source = "./modules/business-unit-folders-tree"

billing_account_id = var.billing_account_id
tf_project_id = module.project-tf.project_id
top_level_folder_name = var.business_unit_1_name
second_level_folders_names = var.business_unit_1_envs
generate_service_account_keys = var.generate_service_account_keys
gcs_location = var.gcs_location
organization_id = var.organization_id
prefix = var.prefix
root_node = var.root_node

}

# Business unit 2

module "business-unit-2-folders-tree" {
source = "./modules/business-unit-folders-tree"

billing_account_id = var.billing_account_id
tf_project_id = module.project-tf.project_id
top_level_folder_name = var.business_unit_2_name
second_level_folders_names = var.business_unit_2_envs
generate_service_account_keys = var.generate_service_account_keys
gcs_location = var.gcs_location
organization_id = var.organization_id
prefix = var.prefix
root_node = var.root_node

}

# Business unit 3

module "business-unit-3-folders-tree" {
source = "./modules/business-unit-folders-tree"

billing_account_id = var.billing_account_id
tf_project_id = module.project-tf.project_id
top_level_folder_name = var.business_unit_3_name
second_level_folders_names = var.business_unit_3_envs
generate_service_account_keys = var.generate_service_account_keys
gcs_location = var.gcs_location
organization_id = var.organization_id
prefix = var.prefix
root_node = var.root_node

}

###############################################################################
# Audit log exports #
###############################################################################

# Audit logs project

module "project-audit" {
source = "terraform-google-modules/project-factory/google//modules/fabric-project"
version = "3.2.0"
parent = var.root_node
billing_account = var.billing_account_id
prefix = var.prefix
name = "audit"
lien_reason = "audit"
activate_apis = var.project_services
viewers = var.audit_viewers
}

# Audit logs destination on BigQuery

module "bq-audit-export" {
source = "terraform-google-modules/log-export/google//modules/bigquery"
version = "3.0.0"
project_id = module.project-audit.project_id
dataset_name = "logs_audit_${replace(var.business_unit_1_name, "-", "_")}"
log_sink_writer_identity = module.log-sink-audit.writer_identity
}

# Audit log sink for business unit 1
# set the organization as parent to export audit logs for all business units

module "log-sink-audit" {
source = "terraform-google-modules/log-export/google"
version = "3.0.0"
filter = "logName: \"/logs/cloudaudit.googleapis.com%2Factivity\" OR logName: \"/logs/cloudaudit.googleapis.com%2Fsystem_event\""
log_sink_name = "logs-audit-${var.business_unit_1_name}"
parent_resource_type = "folder"
parent_resource_id = split("/", module.business-unit-1-folders-tree.top_level_folder_id)[1]
include_children = "true"
unique_writer_identity = "true"
destination_uri = "${module.bq-audit-export.destination_uri}"
}

###############################################################################
# Shared resources (GCR, GCS, KMS, etc.) #
###############################################################################

# Shared resources project

module "project-shared-resources" {
source = "terraform-google-modules/project-factory/google//modules/fabric-project"
version = "3.2.0"
parent = var.root_node
billing_account = var.billing_account_id
prefix = var.prefix
name = "shared"
lien_reason = "shared"
activate_apis = var.project_services
extra_bindings_roles = var.shared_bindings_roles
extra_bindings_members = var.shared_bindings_members
}

# Add further modules here for resources that are common to all business units
# like GCS buckets (used to hold shared assets), Container Registry, KMS, etc.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Two-levels folders tree

This module creates one top-level folder and set of second-level folders, which meant to represent a business unit with set of enviroments underneeth. It also creates per environment GCS bucket and ServiceAccount in a project specified by `tf_project_id` variable.

This set of Terraform files is usually applied manually by an org-level administrator as a first step, and then reapplied only when a new environment needs to be created or an existing one removed, and serves different purposes:

## Managed resources and services

This sample creates several distinct groups of resources:

- one top level folder
- set of second level folders
- set of GCS buckets, which meant to be used for storing terraform state.
- set of service accounts and keys, which meant to be used for automating underneeth infrastructure with terraform.

The number of resources in this sample is kept to a minimum so as to make it generally applicable, more resources can be easily added by leveraging the full array of [Cloud Foundation Toolkit modules](https://github.com/terraform-google-modules), especially in the shared services project.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|:----:|:-----:|:-----:|
| billing\_account\_id | Billing account id used as default for new projects. | string | n/a | yes |
| gcs\_location | GCS bucket location. | string | `"EU"` | no |
| generate\_service\_account\_keys | Generate and store service account keys in the state file. | string | `"false"` | no |
| organization\_id | Organization id. | string | n/a | yes |
| prefix | Prefix used for resources that need unique names. | string | n/a | yes |
| root\_node | Root node for the new hierarchy, either 'organizations/org_id' or 'folders/folder_id'. | string | n/a | yes |
| second\_level\_folders\_names | Second level folders names. | list(string) | n/a | yes |
| tf\_project\_id | Id of a project where service accounts and terraform state buckets should be created | string | n/a | yes |
| top\_level\_folder\_name | Top level folder name. | string | n/a | yes |

## Outputs

| Name | Description |
|------|-------------|
| second\_level\_folders\_ids | Second-level folders IDs. |
| second\_level\_folders\_service\_account\_emails | Service accounts used to run each econd-level folder Terraform modules. |
| second\_level\_folders\_service\_account\_keys | Service account keys used to run each second-level folder Terraform modules. |
| second\_level\_folders\_tf\_gcs\_bucket\_names | GCS buckets used for each second-level folder Terraform state. |
| top\_level\_folder\_id | Top-level folder ID. |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
Loading