From 55a8aca99faeccb44592f803c1fca3c14e167198 Mon Sep 17 00:00:00 2001 From: Simone Ruffilli Date: Mon, 17 Jan 2022 10:25:56 +0100 Subject: [PATCH] Import Fast from dev repository. > > Co-authored-by: Julio Castillo Co-authored-by: Ludovico Magnocavallo Co-authored-by: Simone Ruffilli --- fast/stages/03-project-factory/README.md | 6 + fast/stages/03-project-factory/prod/README.md | 130 ++++++++++++++++++ .../prod/data/defaults.yaml.sample | 22 +++ .../prod/data/projects/project.yaml.sample | 99 +++++++++++++ .../03-project-factory/prod/diagram.png | Bin 0 -> 57470 bytes fast/stages/03-project-factory/prod/main.tf | 57 ++++++++ .../stages/03-project-factory/prod/outputs.tf | 20 +++ .../03-project-factory/prod/variables.tf | 54 ++++++++ 8 files changed, 388 insertions(+) create mode 100644 fast/stages/03-project-factory/README.md create mode 100644 fast/stages/03-project-factory/prod/README.md create mode 100644 fast/stages/03-project-factory/prod/data/defaults.yaml.sample create mode 100644 fast/stages/03-project-factory/prod/data/projects/project.yaml.sample create mode 100644 fast/stages/03-project-factory/prod/diagram.png create mode 100644 fast/stages/03-project-factory/prod/main.tf create mode 100644 fast/stages/03-project-factory/prod/outputs.tf create mode 100644 fast/stages/03-project-factory/prod/variables.tf diff --git a/fast/stages/03-project-factory/README.md b/fast/stages/03-project-factory/README.md new file mode 100644 index 00000000..2beb5158 --- /dev/null +++ b/fast/stages/03-project-factory/README.md @@ -0,0 +1,6 @@ +# Project factory + +The Project Factory (or PF) builds on top of your foundations to create and setup projects (and related resources) to be used for your workloads. +It is organized in folders representing enviroments (e.g. "dev", "prod"), each implemented by a stand-alone terraform [resource factory](https://medium.com/google-cloud/resource-factories-a-descriptive-approach-to-terraform-581b3ebb59c). + +This directory contains a single project factory ([`prod/`](./prod/)) as an example - in order to implement multiple environments (e.g. "prod" and "dev") you'll need to copy the `prod` folder into one folder per environment, then customize each one following the instructions found in [`prod/README.md`](./prod/README.md). \ No newline at end of file diff --git a/fast/stages/03-project-factory/prod/README.md b/fast/stages/03-project-factory/prod/README.md new file mode 100644 index 00000000..3cc9ac7e --- /dev/null +++ b/fast/stages/03-project-factory/prod/README.md @@ -0,0 +1,130 @@ +# Project factory + +The Project Factory (or PF) builds on top of your foundations to create and set up projects (and related resources) to be used for your workloads. +It is organized in folders representing environments (e.g. "dev", "prod"), each implemented by a stand-alone terraform [resource factory](https://medium.com/google-cloud/resource-factories-a-descriptive-approach-to-terraform-581b3ebb59c). + +## Design overview and choices + +![Diagram](diagram.png) + +A single factory creates projects in a well-defined context, according to your resource management structure. In the diagram above, each Team is structured to have specific folders projects for a given environment, such as Production and Development, per the resource management structure configured in stage `01-resman`. + +Projects for each environment across different teams are created by dedicated service accounts, as exemplified in the diagram above. While there's no intrinsic limitation regarding where the project factory can create a given project, the IAM bindings for the service account effectively enforce boundaries (e.g. the production service account shouldn't be able to create or have any access to the development projects, and vice versa). + +The project factory takes care of the following activities: + +* Project creation +* API/Services enablement +* Service accounts creation +* IAM roles assignment for groups and service accounts +* KMS keys roles assignment +* Shared VPC attachment and subnets IAM binding +* DNS zones creation and visibility configuration +* Project-level org policies definition +* Billing setup (billing account attachment and budget configuration) +* Essential contacts definition (for [budget alerts](https://cloud.google.com/billing/docs/how-to/budgets) and [important notifications](https://cloud.google.com/resource-manager/docs/managing-notification-contacts?hl=en)) + + +## How to run this stage + +This stage is meant to be executed after "foundational stages" (i.e. stages [`00-bootstrap`](../../00-bootstrap), [`01-resman`](../../01-resman), [`02-networking`](../../02-networking) and [`02-security`](../../02-security)) have been run. + +It's of course possible to run this stage in isolation, by making sure the architectural prerequisites are satisfied (e.g. networking), and that the Service Account running the stage is granted the roles/permissions below: + +* One service account per environment, each with appropriate permissions + * at the organization level a custom role for networking operations including the following permissions + * `"compute.organizations.enableXpnResource"`, + * `"compute.organizations.disableXpnResource"`, + * `"compute.subnetworks.setIamPolicy"`, + * `"dns.networks.bindPrivateDNSZone"` + * and role `"roles/orgpolicy.policyAdmin"` + * on each folder where projects will be created + * `"roles/logging.admin"` + * `"roles/owner"` + * `"roles/resourcemanager.folderAdmin"` + * `"roles/resourcemanager.projectCreator"` + * on the host project for the Shared VPC + * `"roles/browser"` + * `"roles/compute.viewer"` + * `"roles/dns.admin"` +* If networking is to be used (e.g. for VMs, GKE Clusters or AppEngine flex), VPC Host projects and their subnets should exist when creating projects +* If per-environment DNS sub-zones are required, one "root" zone per environment should exist when creating projects (e.g. prod.gcp.example.com.) + +### Providers configuration + +If you're running this on top of FAST, you should run the following commands to create the provider file, and populate the required variables from the previous stage. + +```bash +# Variable `outputs_location` is set to `../../configs/example` in stage 01-resman +$ cd fabric-fast/stages/03-project-factory/prod +ln -s ../../../configs/example/03-project-factory-prod/providers.tf +``` + +### Variable configuration + +There are two broad sets of variables you will need to fill in: + +- variables shared by other stages (org id, billing account id, etc.), or derived from a resource managed by a different stage (folder id, automation project id, etc.) +- variables specific to resources managed by this stage + +To avoid the tedious job of filling in the first group of variables with values derived from other stages' outputs, the same mechanism used above for the provider configuration can be used to leverage pre-configured `.tfvars` files. + +If you configured a valid path for `outputs_location` in the bootstrap and networking stage, simply link the relevant `terraform-*.auto.tfvars.json` files from this stage's outputs folder (under the path you specified), where the `*` above is set to the name of the stage that produced it. For this stage, a single `.tfvars` file is available: + +```bash +# Variable `outputs_location` is set to `../../configs/example` in stages 01-bootstrap and 02-networking +ln -s ../../../configs/example/03-project-factory-prod/terraform-bootstrap.auto.tfvars.json +ln -s ../../../configs/example/03-project-factory-prod/terraform-networking.auto.tfvars.json +``` + +If you're not running on top of fast, refer to the [Variables](#variables) table at the bottom of this document for a full list of variables, their origin (e.g. a stage or specific to this one), and descriptions explaining their meaning. + + +Besides the values above, a project factory takes 2 additional inputs: + + +* `data/defaults.yaml`, manually configured by adapting the [`prod/data/defaults.yaml.sample`](./prod/data/defaults.yaml.sample), which defines per-environment default values e.g. for billing alerts and labels. + +* `data/projects/*.yaml`, one file per project (optionally grouped in folders), which configures each project. A [`prod/data/projects/project.yaml.sample`](./prod/data/projects/project.yaml.sample) is provided as reference and documentation for the schema. Projects will be named after the filename, e.g. `fast-prod-lab0.yaml` will generate project `fast-prod-lab0`. + +Once the configuration is complete, the project factory can be run with the usual + +```bash +terraform init +terraform apply +``` + + + + + + +## Files + +| name | description | modules | resources | +| ------------------------------ | ----------------- | ---------------------------- | --------- | +| [main.tf](./main.tf) | Project factory. | project-factory | | +| [outputs.tf](./outputs.tf) | Module outputs. | | | +| [variables.tf](./variables.tf) | Module variables. | | | + +## Variables + +| name | description | type | required | default | producer | +| -------------------- | --------------------------------------------------------------------- | :-----------------: | :------: | :-------------------------------------------: | :------------------------: | +| billing_account_id | Billing account id. | string | ✓ | | 00-bootstrap | +| shared_vpc_self_link | Self link for the shared VPC. | string | ✓ | | 02-networking | +| vpc_host_project | Host project for the shared VPC. | string | ✓ | | 02-networking | +| data_dir | Relative path for the folder storing configuration data. | string | | "data/projects" | | +| defaults_file | Relative path for the file storing the project factory configuration. | string | | "data/defaults.yaml" | | +| environment_dns_zone | DNS zone suffix for environment. | string | | null | 02-networking | + +## Outputs + +| name | description | sensitive | consumers | +| -------- | -------------------------------------- | :-------: | --------- | +| projects | Created projects and service accounts. | | | + + + + + diff --git a/fast/stages/03-project-factory/prod/data/defaults.yaml.sample b/fast/stages/03-project-factory/prod/data/defaults.yaml.sample new file mode 100644 index 00000000..577c4bba --- /dev/null +++ b/fast/stages/03-project-factory/prod/data/defaults.yaml.sample @@ -0,0 +1,22 @@ +billing_account_id: 012345-67890A-BCDEF0 + +# [opt] Setup for billing alerts +billing_alert: + amount: 1000 + thresholds: + current: [0.5, 0.8] + forecasted: [0.5, 0.8] + credit_treatment: INCLUDE_ALL_CREDITS + +# [opt] Contacts for billing alerts and important notifications +essential_contacts: ["team-contacts@example.com"] + +# [opt] Labels set for all projects +labels: + environment: prod + department: accounting + application: example-app + foo: bar + +# [opt] Additional notification channels for billing +notification_channels: [] \ No newline at end of file diff --git a/fast/stages/03-project-factory/prod/data/projects/project.yaml.sample b/fast/stages/03-project-factory/prod/data/projects/project.yaml.sample new file mode 100644 index 00000000..7994e7f4 --- /dev/null +++ b/fast/stages/03-project-factory/prod/data/projects/project.yaml.sample @@ -0,0 +1,99 @@ +# [opt] Billing account id - overrides default if set +billing_account_id: 012345-67890A-BCDEF0 + +# [opt] Billing alerts config - overrides default if set +billing_alert: + amount: 10 + thresholds: + current: + - 0.5 + - 0.8 + forecasted: [] + +# [opt] DNS zones to be created as children of the environment_dns_zone defined in defaults +dns_zones: + - lorem + - ipsum + +# [opt] Contacts for billing alerts and important notifications +essential_contacts: + - team-a-contacts@example.com + +# Folder the project will be created as children of +folder_id: folders/012345678901 + +# [opt] Authoritative IAM bindings in group => [roles] format +group_iam: + test-team-foobar@fast-lab-0.gcp-pso-italy.net: + - roles/compute.admin + +# [opt] Authoritative IAM bindings in role => [principals] format +# Generally used to grant roles to service accounts external to the project +iam: + roles/compute.admin: + - serviceAccount:service-account + +# [opt] Service robots and keys they will be assigned as cryptoKeyEncrypterDecrypter +# in service => [keys] format +kms_service_agents: + compute: [key1, key2] + storage: [key1, key2] + +# [opt] Labels for the project - merged with the ones defined in defaults +labels: + environment: prod + +# [opt] Org policy overrides defined at project level +org_policies: + policy_boolean: + constraints/compute.disableGuestAttributesAccess: true + policy_list: + constraints/compute.trustedImageProjects: + inherit_from_parent: null + status: true + suggested_value: null + values: + - projects/fast-prod-iac-core-0 + +# [opt] Service account to create for the project and their roles on the project +# in name => [roles] format +service_accounts: + another-service-account: + - roles/compute.admin + my-service-account: + - roles/compute.admin + +# [opt] APIs to enable on the project. +services: + - storage.googleapis.com + - stackdriver.googleapis.com + - compute.googleapis.com + +# [opt] Roles to assign to the robots service accounts in robot => [roles] format +services_iam: + compute: + - roles/storage.objectViewer + + # [opt] VPC setup. + # If set enables the `compute.googleapis.com` service and configures + # service project attachment +vpc: + + # [opt] If set, enables the container API + gke_setup: + + # Grants "roles/container.hostServiceAgentUser" to the container robot if set + enable_host_service_agent: false + + # Grants "roles/compute.securityAdmin" to the container robot if set + enable_security_admin: true + + # Host project the project will be service project of + host_project: fast-prod-net-spoke-0 + + # [opt] Subnets in the host project where principals will be granted networkUser + # in region/subnet-name => [principals] + subnets_iam: + europe-west1/prod-default-ew1: + - user:foobar@example.com + - serviceAccount:service-account1 \ No newline at end of file diff --git a/fast/stages/03-project-factory/prod/diagram.png b/fast/stages/03-project-factory/prod/diagram.png new file mode 100644 index 0000000000000000000000000000000000000000..b942ea47d934695831b1838d41766db699e9b64b GIT binary patch literal 57470 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Ν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 literal 0 HcmV?d00001 diff --git a/fast/stages/03-project-factory/prod/main.tf b/fast/stages/03-project-factory/prod/main.tf new file mode 100644 index 00000000..e1c05e51 --- /dev/null +++ b/fast/stages/03-project-factory/prod/main.tf @@ -0,0 +1,57 @@ +/** + * 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. + */ + +# tfdoc:file:description Project factory. + + +locals { + _defaults = yamldecode(file(var.defaults_file)) + _defaults_net = { + billing_account_id = var.billing_account_id + environment_dns_zone = var.environment_dns_zone + shared_vpc_self_link = var.shared_vpc_self_link + vpc_host_project = var.vpc_host_project + } + defaults = merge(local._defaults, local._defaults_net) + projects = { + for f in fileset("${var.data_dir}", "**/*.yaml") : + trimsuffix(f, ".yaml") => yamldecode(file("${var.data_dir}/${f}")) + } +} + +module "projects" { + #TODO(sruffilli): Pin to release + source = "github.com/terraform-google-modules/cloud-foundation-fabric/examples/factories/project-factory" + for_each = local.projects + defaults = local.defaults + project_id = each.key + billing_account_id = try(each.value.billing_account_id, null) + billing_alert = try(each.value.billing_alert, null) + dns_zones = try(each.value.dns_zones, []) + essential_contacts = try(each.value.essential_contacts, []) + folder_id = each.value.folder_id + group_iam = try(each.value.group_iam, {}) + iam = try(each.value.iam, {}) + kms_service_agents = try(each.value.kms, {}) + labels = try(each.value.labels, {}) + org_policies = try(each.value.org_policies, null) + service_accounts = try(each.value.service_accounts, {}) + services = try(each.value.services, []) + services_iam = try(each.value.services_iam, {}) + vpc = try(each.value.vpc, null) +} + + diff --git a/fast/stages/03-project-factory/prod/outputs.tf b/fast/stages/03-project-factory/prod/outputs.tf new file mode 100644 index 00000000..59ecff95 --- /dev/null +++ b/fast/stages/03-project-factory/prod/outputs.tf @@ -0,0 +1,20 @@ +/** + * 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. + */ + +output "projects" { + description = "Created projects and service accounts." + value = module.projects +} diff --git a/fast/stages/03-project-factory/prod/variables.tf b/fast/stages/03-project-factory/prod/variables.tf new file mode 100644 index 00000000..8bb9f035 --- /dev/null +++ b/fast/stages/03-project-factory/prod/variables.tf @@ -0,0 +1,54 @@ +/** + * 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. + */ + +#TODO: tfdoc annotations + +variable "billing_account_id" { + # tfdoc:variable:source 00-bootstrap + description = "Billing account id." + type = string +} + +variable "data_dir" { + description = "Relative path for the folder storing configuration data." + type = string + default = "data/projects" +} + +variable "environment_dns_zone" { + # tfdoc:variable:source 02-networking + description = "DNS zone suffix for environment." + type = string + default = null +} + +variable "defaults_file" { + description = "Relative path for the file storing the project factory configuration." + type = string + default = "data/defaults.yaml" +} + +variable "shared_vpc_self_link" { + # tfdoc:variable:source 02-networking + description = "Self link for the shared VPC." + type = string +} + +variable "vpc_host_project" { + # tfdoc:variable:source 02-networking + description = "Host project for the shared VPC." + type = string +}