diff --git a/fast/stages/3-project-factory/prod/README.md b/fast/stages/3-project-factory/prod/README.md new file mode 100644 index 00000000..b9eb9c76 --- /dev/null +++ b/fast/stages/3-project-factory/prod/README.md @@ -0,0 +1,129 @@ +# 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 + +

+ Project factory diagram +

+ +A single factory creates projects in a well-defined context, according to your resource management structure. For example, 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 projects, 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`](../../0-bootstrap), [`01-resman`](../../1-resman), 02-networking (either [VPN](../../2-networking-b-vpn), [NVA](../../2-networking-c-nva), [NVA with BGP support](../../2-networking-e-nva-bgp)) and [`02-security`](../../2-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 are 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 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., dev.gcp.example.com.) + +### Provider and Terraform variables + +As all other FAST stages, the [mechanism used to pass variable values and pre-built provider files from one stage to the next](../../0-bootstrap/README.md#output-files-and-cross-stage-variables) is also leveraged here. + +The commands to link or copy the provider and terraform variable files can be easily derived from the `stage-links.sh` script in the FAST root folder, passing it a single argument with the local output files folder (if configured) or the GCS output bucket in the automation project (derived from stage 0 outputs). The following examples demonstrate both cases, and the resulting commands that then need to be copy/pasted and run. + +```bash +../../../stage-links.sh ~/fast-config + +# copy and paste the following commands for '3-project-factory' + +ln -s ~/fast-config/providers/3-project-factory-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/2-networking.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/2-security.auto.tfvars.json ./ +``` + +```bash +../../../stage-links.sh gs://xxx-prod-iac-core-outputs-0 + +# copy and paste the following commands for '3-project-factory' + +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/providers/3-project-factory-providers.tf ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/globals.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/0-bootstrap.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/1-resman.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-networking.auto.tfvars.json ./ +gcloud alpha storage cp gs://xxx-prod-iac-core-outputs-0/tfvars/2-security.auto.tfvars.json ./ +``` + +If you're not using 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 [`data/defaults.yaml`](./data/defaults.yaml), 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 [`data/projects/project.yaml`](./data/projects/project.yaml.sample) is provided as reference and documentation for the schema. Projects will be named after the filename, e.g., `fast-dev-lab0.yaml` will create project `fast-dev-lab0`. + +Once the configuration is complete, run the project factory by running + +```bash +terraform init +terraform apply +``` + + + + +## Files + +| name | description | modules | +|---|---|---| +| [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](variables.tf#L19) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap | +| [prefix](variables.tf#L60) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap | +| [data_dir](variables.tf#L32) | Relative path for the folder storing configuration data. | string | | "data/projects" | | +| [defaults_file](variables.tf#L38) | Relative path for the file storing the project factory configuration. | string | | "data/defaults.yaml" | | +| [environment_dns_zone](variables.tf#L44) | DNS zone suffix for environment. | string | | null | 2-networking | +| [host_project_ids](variables.tf#L51) | Host project for the shared VPC. | object({…}) | | null | 2-networking | +| [vpc_self_links](variables.tf#L71) | Self link for the shared VPC. | object({…}) | | null | 2-networking | + +## Outputs + +| name | description | sensitive | consumers | +|---|---|:---:|---| +| [projects](outputs.tf#L17) | Created projects and service accounts. | | | + + diff --git a/fast/stages/3-project-factory/prod/data/defaults.yaml b/fast/stages/3-project-factory/prod/data/defaults.yaml new file mode 100644 index 00000000..994ca6b2 --- /dev/null +++ b/fast/stages/3-project-factory/prod/data/defaults.yaml @@ -0,0 +1,23 @@ +# skip boilerplate check + +billing_account_id: 01EBC4-8CD936-3108EA + +# [opt] Setup for billing alerts +billing_alert: + amount: 1000 + thresholds: + current: [0.5, 0.8] + forecasted: [1.2, 1.5] + credit_treatment: INCLUDE_ALL_CREDITS + +# [opt] Contacts for billing alerts and important notifications +essential_contacts: ["admin@zfnd.org"] + +# [opt] Labels set for all projects +labels: + environment: prod + department: engineering + + +# [opt] Additional notification channels for billing +notification_channels: [] diff --git a/fast/stages/3-project-factory/prod/data/projects/prod-services.yaml b/fast/stages/3-project-factory/prod/data/projects/prod-services.yaml new file mode 100644 index 00000000..af0c03ce --- /dev/null +++ b/fast/stages/3-project-factory/prod/data/projects/prod-services.yaml @@ -0,0 +1,106 @@ +# skip boilerplate check + +# [opt] Billing alerts config - overrides default if set +billing_alert: + amount: 5000 + thresholds: + current: + - 0.8 + - 1.0 + forecasted: [] + credit_treatment: INCLUDE_ALL_CREDITS + +# [opt] DNS zones to be created as children of the environment_dns_zone defined in defaults +dns_zones: [] + +# [opt] Contacts for billing alerts and important notifications +essential_contacts: + - devops@zfnd.org + +# Folder the project will be created as children of +folder_id: folders/516886086110 + +# [opt] Authoritative IAM bindings in group => [roles] format +group_iam: + engineers@zfnd.org: + - roles/viewer + +# [opt] Authoritative IAM bindings in role => [principals] format +# Generally used to grant roles to service accounts external to the project +iam: + roles/iam.workloadIdentityUser: + - principalSet://iam.googleapis.com/projects/771011584009/locations/global/workloadIdentityPools/zfnd-bootstrap/* + # roles/editor: + # - serviceAccount:1059680692020@cloudservices.gserviceaccount.com + +# [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 + application: services + scope: ecosystem + +# [opt] Org policy overrides defined at project level +org_policies: + iam.allowedPolicyMemberDomains: + rules: + - allow: + all: true + +# [opt] Service account to create for the project and their roles on the project +# in name => [roles] format +service_accounts: + instance-deployer: + - roles/compute.instanceAdmin + - roles/compute.storageAdmin + - roles/compute.loadBalancerAdmin + - roles/errorreporting.user + - roles/logging.logWriter + - roles/monitoring.metricWriter + - roles/artifactregistry.reader + - roles/iam.serviceAccountUser + - roles/iam.workloadIdentityUser + +# [opt] APIs to enable on the project. +services: + # - artifactregistry.googleapis.com + - compute.googleapis.com + # - clouddebugger.googleapis.com + - clouderrorreporting.googleapis.com + - cloudresourcemanager.googleapis.com + - containeranalysis.googleapis.com + - logging.googleapis.com + - monitoring.googleapis.com + - osconfig.googleapis.com + - networkmanagement.googleapis.com + - stackdriver.googleapis.com + - storage.googleapis.com + - iap.googleapis.com + +# [opt] Roles to assign to the service identities in service => [roles] format +service_identities_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: null + + # Host project the project will be service project of + host_project: zfnd-prod-net-spoke-0 + + # [opt] Subnets in the host project where principals will be granted networkUser + # in region/subnet-name => [principals] + subnets_iam: + us-east1/prod-default-ue1: + # - user:gustavo@zfnd.org + - serviceAccount:instance-deployer@zfnd-prod-zebra.iam.gserviceaccount.com diff --git a/fast/stages/3-project-factory/prod/data/projects/prod-zebra.yaml b/fast/stages/3-project-factory/prod/data/projects/prod-zebra.yaml new file mode 100644 index 00000000..4f0fba24 --- /dev/null +++ b/fast/stages/3-project-factory/prod/data/projects/prod-zebra.yaml @@ -0,0 +1,110 @@ +# skip boilerplate check + +# [opt] Billing alerts config - overrides default if set +billing_alert: + amount: 5000 + thresholds: + current: + - 0.8 + - 1.0 + forecasted: [] + credit_treatment: INCLUDE_ALL_CREDITS + +# [opt] DNS zones to be created as children of the environment_dns_zone defined in defaults +dns_zones: [] + +# [opt] Contacts for billing alerts and important notifications +essential_contacts: + - devops@zfnd.org + +# Folder the project will be created as children of +folder_id: folders/516886086110 + +# [opt] Authoritative IAM bindings in group => [roles] format +group_iam: + engineers@zfnd.org: + - roles/viewer + +# [opt] Authoritative IAM bindings in role => [principals] format +# Generally used to grant roles to service accounts external to the project +iam: + roles/iam.workloadIdentityUser: + - principalSet://iam.googleapis.com/projects/771011584009/locations/global/workloadIdentityPools/zfnd-bootstrap/* + # roles/editor: + # - serviceAccount:1059680692020@cloudservices.gserviceaccount.com + +# [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 + application: zebra + firebase: enabled + +# [opt] Org policy overrides defined at project level +org_policies: + iam.allowedPolicyMemberDomains: + rules: + - allow: + all: true + +# [opt] Service account to create for the project and their roles on the project +# in name => [roles] format +service_accounts: + instance-deployer: + - roles/compute.instanceAdmin + - roles/compute.storageAdmin + - roles/compute.loadBalancerAdmin + - roles/errorreporting.user + - roles/logging.logWriter + - roles/monitoring.metricWriter + - roles/artifactregistry.reader + - roles/iam.serviceAccountUser + - roles/iam.workloadIdentityUser + documentation-publisher: + - roles/firebasehosting.admin + +# [opt] APIs to enable on the project. +services: + # - artifactregistry.googleapis.com + - compute.googleapis.com + - clouderrorreporting.googleapis.com + - cloudresourcemanager.googleapis.com + - containeranalysis.googleapis.com + - firebase.googleapis.com + - iap.googleapis.com + - logging.googleapis.com + - monitoring.googleapis.com + - osconfig.googleapis.com + - networkmanagement.googleapis.com + - serviceusage.googleapis.com + - stackdriver.googleapis.com + - storage.googleapis.com + + +# [opt] Roles to assign to the service identities in service => [roles] format +service_identities_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: null + + # Host project the project will be service project of + host_project: zfnd-prod-net-spoke-0 + + # [opt] Subnets in the host project where principals will be granted networkUser + # in region/subnet-name => [principals] + subnets_iam: + us-east1/prod-default-ue1: + # - user:gustavo@zfnd.org + - serviceAccount:instance-deployer@zfnd-prod-zebra.iam.gserviceaccount.com diff --git a/fast/stages/3-project-factory/prod/data/projects/project.yaml.sample b/fast/stages/3-project-factory/prod/data/projects/project.yaml.sample new file mode 100644 index 00000000..5311019d --- /dev/null +++ b/fast/stages/3-project-factory/prod/data/projects/project.yaml.sample @@ -0,0 +1,103 @@ +# skip boilerplate check + +# [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: [] + credit_treatment: INCLUDE_ALL_CREDITS + +# [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: dev + +# [opt] Org policy overrides defined at project level +org_policies: + compute.disableGuestAttributesAccess: + rules: + - enforce: true + compute.trustedImageProjects: + rules: + - allow: + values: + - projects/fast-dev-iac-core-0 + compute.vmExternalIpAccess: + rules: + - deny: + all: true + +# [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 service identities in service => [roles] format +service_identities_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-dev-net-spoke-0 + + # [opt] Subnets in the host project where principals will be granted networkUser + # in region/subnet-name => [principals] + subnets_iam: + europe-west1/dev-default-ew1: + - user:foobar@example.com + - serviceAccount:service-account1 diff --git a/fast/stages/3-project-factory/prod/diagram.png b/fast/stages/3-project-factory/prod/diagram.png new file mode 100644 index 00000000..b942ea47 Binary files /dev/null and b/fast/stages/3-project-factory/prod/diagram.png differ diff --git a/fast/stages/3-project-factory/prod/diagram.svg b/fast/stages/3-project-factory/prod/diagram.svg new file mode 100644 index 00000000..d7821c60 --- /dev/null +++ b/fast/stages/3-project-factory/prod/diagram.svg @@ -0,0 +1,1530 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fast/stages/3-project-factory/prod/main.tf b/fast/stages/3-project-factory/prod/main.tf new file mode 100644 index 00000000..72b1a3cb --- /dev/null +++ b/fast/stages/3-project-factory/prod/main.tf @@ -0,0 +1,115 @@ +/** + * 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 = try(var.vpc_self_links["prod-spoke-0"], null) + vpc_host_project = try(var.host_project_ids["prod-spoke-0"], null) + } + 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" { + source = "../../../../blueprints/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 = try(each.value.folder_id, local.defaults.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) + prefix = var.prefix + service_accounts = try(each.value.service_accounts, {}) + service_accounts_iam = try(each.value.service_accounts_iam, {}) + services = try(each.value.services, []) + service_identities_iam = try(each.value.service_identities_iam, {}) + vpc = try(each.value.vpc, null) +} + +# Enables Firebase services for the new project created above. +resource "google_firebase_project" "firebase-zebra-docs" { + provider = google-beta + project = "zfnd-prod-zebra" + + # Waits for the required APIs to be enabled. + depends_on = [ + module.projects.services + ] +} + +resource "google_firebase_web_app" "zebra-book" { + provider = google-beta + project = "zfnd-prod-zebra" + display_name = "Zebra Book" + deletion_policy = "DELETE" + + depends_on = [google_firebase_project.firebase-zebra-docs] +} + +resource "google_firebase_hosting_site" "zebra-book" { + provider = google-beta + project = "zfnd-prod-zebra" + site_id = "zebra-docs-book" + app_id = google_firebase_web_app.zebra-book.app_id +} + +resource "google_firebase_web_app" "zebra-docs-internal" { + provider = google-beta + project = "zfnd-prod-zebra" + display_name = "Zebra Docs - Internal" + deletion_policy = "DELETE" + + depends_on = [google_firebase_project.firebase-zebra-docs] +} + +resource "google_firebase_hosting_site" "zebra-docs-internal" { + provider = google-beta + project = "zfnd-prod-zebra" + site_id = "zebra-docs-internal" + app_id = google_firebase_web_app.zebra-docs-internal.app_id +} + +resource "google_firebase_web_app" "zebra-docs-external" { + provider = google-beta + project = "zfnd-prod-zebra" + display_name = "Zebra Docs - External" + deletion_policy = "DELETE" + + depends_on = [google_firebase_project.firebase-zebra-docs] +} + +resource "google_firebase_hosting_site" "zebra-docs-external" { + provider = google-beta + project = "zfnd-prod-zebra" + site_id = "zebra-docs-external" + app_id = google_firebase_web_app.zebra-docs-external.app_id +} diff --git a/fast/stages/3-project-factory/prod/outputs.tf b/fast/stages/3-project-factory/prod/outputs.tf new file mode 100644 index 00000000..59ecff95 --- /dev/null +++ b/fast/stages/3-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/3-project-factory/prod/variables.tf b/fast/stages/3-project-factory/prod/variables.tf new file mode 100644 index 00000000..934f4e40 --- /dev/null +++ b/fast/stages/3-project-factory/prod/variables.tf @@ -0,0 +1,142 @@ +/** + * 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" { + # tfdoc:variable:source 0-bootstrap + description = "Billing account id. If billing account is not part of the same org set `is_org_level` to false." + type = object({ + id = string + is_org_level = optional(bool, true) + }) + validation { + condition = var.billing_account.is_org_level != null + error_message = "Invalid `null` value for `billing_account.is_org_level`." + } +} + +variable "data_dir" { + description = "Relative path for the folder storing configuration data." + type = string + default = "data/projects" +} + +variable "defaults_file" { + description = "Relative path for the file storing the project factory configuration." + type = string + default = "data/defaults.yaml" +} + +variable "environment_dns_zone" { + # tfdoc:variable:source 2-networking + description = "DNS zone suffix for environment." + type = string + default = null +} + +variable "host_project_ids" { + # tfdoc:variable:source 2-networking + description = "Host project for the shared VPC." + type = object({ + prod-spoke-0 = string + }) + default = null +} + +variable "prefix" { + # tfdoc:variable:source 0-bootstrap + description = "Prefix used for resources that need unique names. Use 9 characters or less." + type = string + + validation { + condition = try(length(var.prefix), 0) < 10 + error_message = "Use a maximum of 9 characters for prefix." + } +} + +variable "vpc_self_links" { + # tfdoc:variable:source 2-networking + description = "Self link for the shared VPC." + type = object({ + prod-spoke-0 = string + }) + default = null +} + +# self-hosted runners variables + +variable "project_id" { + type = string + description = "The project id to deploy Github Runner MIG" +} + +variable "image" { + type = string + description = "The github runner image" +} + +variable "repo_url" { + type = string + description = "Repo URL for the Github Action" +} + + +variable "repo_name" { + type = string + description = "Name of the repo for the Github Action" +} + + +variable "repo_owner" { + type = string + description = "Owner of the repo for the Github Action" +} + +variable "gh_token" { + type = string + description = "Github token that is used for generating Self Hosted Runner Token" +} + +variable "region" { + type = string + description = "The GCP region to deploy instances into" + default = "us-east1" +} + +variable "subnetwork_project" { + type = string + description = "The ID of the project in which the subnetwork belongs. If it is not provided, the project_id is used." + default = "" +} + +variable "subnet_name" { + type = string + description = "Name for the subnet" + default = "" +} + +variable "subnet_ip" { + type = string + description = "IP range for the subnet" + default = "" +} + +variable "service_account" { + description = "Service account email address" + type = string + default = "" +} \ No newline at end of file