FAST: configuration switches for features (#703)

* example implementation of top-level switches

* data platform as a fast feature

* decouple teams and project factory

* teams disable fixes

* optional pf

* networking stage

* remove var from stage 2s, security
This commit is contained in:
Ludovico Magnocavallo 2022-06-28 17:33:37 +02:00 committed by GitHub
parent 3863e502bf
commit 66c4fffd76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 478 additions and 266 deletions

View File

@ -461,31 +461,32 @@ The remaining configuration is manual, as it regards the repositories themselves
| name | description | type | required | default | producer |
|---|---|:---:|:---:|:---:|:---:|
| [billing_account](variables.tf#L17) | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object&#40;&#123;&#10; id &#61; string&#10; organization_id &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | |
| [organization](variables.tf#L162) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | |
| [prefix](variables.tf#L177) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
| [organization](variables.tf#L179) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | |
| [prefix](variables.tf#L194) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | |
| [bootstrap_user](variables.tf#L25) | Email of the nominal user running this stage for the first time. | <code>string</code> | | <code>null</code> | |
| [cicd_repositories](variables.tf#L31) | CI/CD repository configuration. Identity providers reference keys in the `federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object&#40;&#123;&#10; bootstrap &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10; cicd &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10; resman &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [custom_role_names](variables.tf#L83) | Names of custom roles defined at the org level. | <code title="object&#40;&#123;&#10; organization_iam_admin &#61; string&#10; service_project_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; organization_iam_admin &#61; &#34;organizationIamAdmin&#34;&#10; service_project_network_admin &#61; &#34;serviceProjectNetworkAdmin&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [federated_identity_providers](variables.tf#L95) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | <code title="map&#40;object&#40;&#123;&#10; attribute_condition &#61; string&#10; issuer &#61; string&#10; custom_settings &#61; object&#40;&#123;&#10; issuer_uri &#61; string&#10; allowed_audiences &#61; list&#40;string&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [groups](variables.tf#L109) | Group names to grant organization-level permissions. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp-billing-admins &#61; &#34;gcp-billing-admins&#34;,&#10; gcp-devops &#61; &#34;gcp-devops&#34;,&#10; gcp-network-admins &#61; &#34;gcp-network-admins&#34;&#10; gcp-organization-admins &#61; &#34;gcp-organization-admins&#34;&#10; gcp-security-admins &#61; &#34;gcp-security-admins&#34;&#10; gcp-support &#61; &#34;gcp-support&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [iam](variables.tf#L123) | Organization-level custom IAM settings in role => [principal] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam_additive](variables.tf#L129) | Organization-level custom IAM settings in role => [principal] format for non-authoritative bindings. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [log_sinks](variables.tf#L137) | Org-level log sinks, in name => {type, filter} format. | <code title="map&#40;object&#40;&#123;&#10; filter &#61; string&#10; type &#61; string&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; audit-logs &#61; &#123;&#10; filter &#61; &#34;logName:&#92;&#34;&#47;logs&#47;cloudaudit.googleapis.com&#37;2Factivity&#92;&#34; OR logName:&#92;&#34;&#47;logs&#47;cloudaudit.googleapis.com&#37;2Fsystem_event&#92;&#34;&#34;&#10; type &#61; &#34;bigquery&#34;&#10; &#125;&#10; vpc-sc &#61; &#123;&#10; filter &#61; &#34;protoPayload.metadata.&#64;type&#61;&#92;&#34;type.googleapis.com&#47;google.cloud.audit.VpcServiceControlAuditMetadata&#92;&#34;&#34;&#10; type &#61; &#34;bigquery&#34;&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L171) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | <code>string</code> | | <code>null</code> | |
| [fast_features](variables.tf#L95) | Selective control for top-level FAST features. | <code title="object&#40;&#123;&#10; data_platform &#61; bool&#10; project_factory &#61; bool&#10; sandbox &#61; bool&#10; teams &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_platform &#61; true&#10; project_factory &#61; true&#10; sandbox &#61; true&#10; teams &#61; true&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [federated_identity_providers](variables.tf#L112) | Workload Identity Federation pools. The `cicd_repositories` variable references keys here. | <code title="map&#40;object&#40;&#123;&#10; attribute_condition &#61; string&#10; issuer &#61; string&#10; custom_settings &#61; object&#40;&#123;&#10; issuer_uri &#61; string&#10; allowed_audiences &#61; list&#40;string&#41;&#10; &#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [groups](variables.tf#L126) | Group names to grant organization-level permissions. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp-billing-admins &#61; &#34;gcp-billing-admins&#34;,&#10; gcp-devops &#61; &#34;gcp-devops&#34;,&#10; gcp-network-admins &#61; &#34;gcp-network-admins&#34;&#10; gcp-organization-admins &#61; &#34;gcp-organization-admins&#34;&#10; gcp-security-admins &#61; &#34;gcp-security-admins&#34;&#10; gcp-support &#61; &#34;gcp-support&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [iam](variables.tf#L140) | Organization-level custom IAM settings in role => [principal] format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [iam_additive](variables.tf#L146) | Organization-level custom IAM settings in role => [principal] format for non-authoritative bindings. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | |
| [log_sinks](variables.tf#L154) | Org-level log sinks, in name => {type, filter} format. | <code title="map&#40;object&#40;&#123;&#10; filter &#61; string&#10; type &#61; string&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; audit-logs &#61; &#123;&#10; filter &#61; &#34;logName:&#92;&#34;&#47;logs&#47;cloudaudit.googleapis.com&#37;2Factivity&#92;&#34; OR logName:&#92;&#34;&#47;logs&#47;cloudaudit.googleapis.com&#37;2Fsystem_event&#92;&#34;&#34;&#10; type &#61; &#34;bigquery&#34;&#10; &#125;&#10; vpc-sc &#61; &#123;&#10; filter &#61; &#34;protoPayload.metadata.&#64;type&#61;&#92;&#34;type.googleapis.com&#47;google.cloud.audit.VpcServiceControlAuditMetadata&#92;&#34;&#34;&#10; type &#61; &#34;bigquery&#34;&#10; &#125;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [outputs_location](variables.tf#L188) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | <code>string</code> | | <code>null</code> | |
## Outputs
| name | description | sensitive | consumers |
|---|---|:---:|---|
| [automation](outputs.tf#L87) | Automation resources. | | |
| [billing_dataset](outputs.tf#L92) | BigQuery dataset prepared for billing export. | | |
| [cicd_repositories](outputs.tf#L97) | CI/CD repository configurations. | | |
| [custom_roles](outputs.tf#L109) | Organization-level custom roles. | | |
| [federated_identity](outputs.tf#L114) | Workload Identity Federation pool and providers. | | |
| [outputs_bucket](outputs.tf#L124) | GCS bucket where generated output files are stored. | | |
| [project_ids](outputs.tf#L129) | Projects created by this stage. | | |
| [providers](outputs.tf#L149) | Terraform provider files for this stage and dependent stages. | ✓ | <code>stage-01</code> |
| [service_accounts](outputs.tf#L138) | Automation service accounts created by this stage. | | |
| [tfvars](outputs.tf#L158) | Terraform variable files for the following stages. | ✓ | |
| [automation](outputs.tf#L88) | Automation resources. | | |
| [billing_dataset](outputs.tf#L93) | BigQuery dataset prepared for billing export. | | |
| [cicd_repositories](outputs.tf#L98) | CI/CD repository configurations. | | |
| [custom_roles](outputs.tf#L110) | Organization-level custom roles. | | |
| [federated_identity](outputs.tf#L115) | Workload Identity Federation pool and providers. | | |
| [outputs_bucket](outputs.tf#L125) | GCS bucket where generated output files are stored. | | |
| [project_ids](outputs.tf#L130) | Projects created by this stage. | | |
| [providers](outputs.tf#L150) | Terraform provider files for this stage and dependent stages. | ✓ | <code>stage-01</code> |
| [service_accounts](outputs.tf#L139) | Automation service accounts created by this stage. | | |
| [tfvars](outputs.tf#L159) | Terraform variable files for the following stages. | ✓ | |
<!-- END TFDOC -->

View File

@ -68,6 +68,7 @@ locals {
}
tfvars_globals = {
billing_account = var.billing_account
fast_features = var.fast_features
groups = var.groups
organization = var.organization
prefix = var.prefix

View File

@ -92,6 +92,23 @@ variable "custom_role_names" {
}
}
variable "fast_features" {
description = "Selective control for top-level FAST features."
type = object({
data_platform = bool
project_factory = bool
sandbox = bool
teams = bool
})
default = {
data_platform = true
project_factory = true
sandbox = true
teams = true
}
nullable = false
}
variable "federated_identity_providers" {
description = "Workload Identity Federation pools. The `cicd_repositories` variable references keys here."
type = map(object({

View File

@ -1,11 +1,10 @@
# CI/CD bootstrap
The primary purpose of this stage is to set up your CI/CD project structure automatically, with most of the
necessary configuration to run the pipelines out of the box.
The primary purpose of this stage is to set up your CI/CD project structure automatically, with most of the necessary configuration to run the pipelines out of the box.
## How to run this stage
This stage is meant to be executed after the [bootstrap](../00-bootstrap) stage has run, as it leverages the automation service account and bucket created there.
This stage is meant to be executed after the [bootstrap](../00-bootstrap) stage has run, as it leverages the automation service account and bucket created there.
The entire stage is optional, you may also choose to create your repositories manually.
### Providers configuration
@ -51,7 +50,7 @@ cp ../00-bootstrap/terraform.tfvars .
A second set of variables is specific to this stage, they are all optional so if you need to customize them, create an extra `terraform.tfvars` file or add them to the file copied from bootstrap.
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. The sections below also describe some of the possible customizations.
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. The sections below also describe some of the possible customizations.
### CI/CD systems
@ -89,7 +88,7 @@ and such, the `00-cicd` stage creates all the repositories in your CI/CD system
configuration is essentially a combination of all the `cicd_repositories` variables of the other stages
plus additional CI/CD system specific configuration information.
This is an example of configuring the repositories in this stage.
This is an example of configuring the repositories in this stage.
```hcl
cicd_repositories = {
@ -163,7 +162,6 @@ The `type` attribute can be set to one of the supported repository types: `githu
Once the stage is applied the generated output files will contain pre-configured workflow files for each repository, that will use Workload Identity Federation via a dedicated service account for each repository to impersonate the automation service account for the stage.
Once done, you can run this stage:
```bash

View File

@ -160,13 +160,14 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
| [billing.tf](./billing.tf) | Billing resources for external billing use cases. | <code>organization</code> | <code>google_billing_account_iam_member</code> |
| [branch-data-platform.tf](./branch-data-platform.tf) | Data Platform stages resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
| [branch-networking.tf](./branch-networking.tf) | Networking stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
| [branch-project-factory.tf](./branch-project-factory.tf) | Project factory stage resources. | <code>gcs</code> · <code>iam-service-account</code> | |
| [branch-sandbox.tf](./branch-sandbox.tf) | Sandbox stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
| [branch-security.tf](./branch-security.tf) | Security stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
| [branch-teams.tf](./branch-teams.tf) | Team stage resources. | <code>folder</code> · <code>gcs</code> · <code>iam-service-account</code> | |
| [cicd-data-platform.tf](./cicd-data-platform.tf) | CI/CD resources for the data platform branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
| [cicd-networking.tf](./cicd-networking.tf) | CI/CD resources for the networking branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
| [cicd-project-factory.tf](./cicd-project-factory.tf) | CI/CD resources for the teams branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
| [cicd-security.tf](./cicd-security.tf) | CI/CD resources for the security branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
| [cicd-teams.tf](./cicd-teams.tf) | CI/CD resources for the teams branch. | <code>iam-service-account</code> · <code>source-repository</code> | |
| [main.tf](./main.tf) | Module-level locals and resources. | | |
| [organization.tf](./organization.tf) | Organization policies. | <code>organization</code> | <code>google_organization_iam_member</code> |
| [outputs-files.tf](./outputs-files.tf) | Output files persistence to local filesystem. | | <code>local_file</code> |
@ -180,28 +181,29 @@ Due to its simplicity, this stage lends itself easily to customizations: adding
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables.tf#L20) | Automation resources created by the bootstrap stage. | <code title="object&#40;&#123;&#10; outputs_bucket &#61; string&#10; project_id &#61; string&#10; project_number &#61; string&#10; federated_identity_pool &#61; string&#10; federated_identity_providers &#61; map&#40;object&#40;&#123;&#10; issuer &#61; string&#10; issuer_uri &#61; string&#10; name &#61; string&#10; principal_tpl &#61; string&#10; principalset_tpl &#61; string&#10; &#125;&#41;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
| [billing_account](variables.tf#L38) | Billing account id and organization id ('nnnnnnnn' or null). | <code title="object&#40;&#123;&#10; id &#61; string&#10; organization_id &#61; number&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
| [organization](variables.tf#L141) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
| [prefix](variables.tf#L165) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
| [organization](variables.tf#L159) | Organization details. | <code title="object&#40;&#123;&#10; domain &#61; string&#10; id &#61; number&#10; customer_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>00-bootstrap</code> |
| [prefix](variables.tf#L183) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>00-bootstrap</code> |
| [cicd_repositories](variables.tf#L47) | CI/CD repository configuration. Identity providers reference keys in the `automation.federated_identity_providers` variable. Set to null to disable, or set individual repositories to null if not needed. | <code title="object&#40;&#123;&#10; data_platform_dev &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10; data_platform_prod &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10; networking &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10; project_factory_dev &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10; project_factory_prod &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10; security &#61; object&#40;&#123;&#10; branch &#61; string&#10; identity_provider &#61; string&#10; name &#61; string&#10; type &#61; string&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [custom_roles](variables.tf#L117) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; service_project_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>00-bootstrap</code> |
| [groups](variables.tf#L126) | Group names to grant organization-level permissions. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp-billing-admins &#61; &#34;gcp-billing-admins&#34;,&#10; gcp-devops &#61; &#34;gcp-devops&#34;,&#10; gcp-network-admins &#61; &#34;gcp-network-admins&#34;&#10; gcp-organization-admins &#61; &#34;gcp-organization-admins&#34;&#10; gcp-security-admins &#61; &#34;gcp-security-admins&#34;&#10; gcp-support &#61; &#34;gcp-support&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | <code>00-bootstrap</code> |
| [organization_policy_configs](variables.tf#L151) | Organization policies customization. | <code title="object&#40;&#123;&#10; allowed_policy_member_domains &#61; list&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [outputs_location](variables.tf#L159) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | <code>string</code> | | <code>null</code> | |
| [tag_names](variables.tf#L176) | Customized names for resource management tags. | <code title="object&#40;&#123;&#10; context &#61; string&#10; environment &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; context &#61; &#34;context&#34;&#10; environment &#61; &#34;environment&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [team_folders](variables.tf#L193) | Team folders to be created. Format is described in a code comment. | <code title="map&#40;object&#40;&#123;&#10; descriptive_name &#61; string&#10; group_iam &#61; map&#40;list&#40;string&#41;&#41;&#10; impersonation_groups &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>null</code> | |
| [fast_features](variables.tf#L126) | Selective control for top-level FAST features. | <code title="object&#40;&#123;&#10; data_platform &#61; bool&#10; project_factory &#61; bool&#10; sandbox &#61; bool&#10; teams &#61; bool&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; data_platform &#61; true&#10; project_factory &#61; true&#10; sandbox &#61; true&#10; teams &#61; true&#10;&#125;">&#123;&#8230;&#125;</code> | <code>00-bootstrap</code> |
| [groups](variables.tf#L144) | Group names to grant organization-level permissions. | <code>map&#40;string&#41;</code> | | <code title="&#123;&#10; gcp-billing-admins &#61; &#34;gcp-billing-admins&#34;,&#10; gcp-devops &#61; &#34;gcp-devops&#34;,&#10; gcp-network-admins &#61; &#34;gcp-network-admins&#34;&#10; gcp-organization-admins &#61; &#34;gcp-organization-admins&#34;&#10; gcp-security-admins &#61; &#34;gcp-security-admins&#34;&#10; gcp-support &#61; &#34;gcp-support&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | <code>00-bootstrap</code> |
| [organization_policy_configs](variables.tf#L169) | Organization policies customization. | <code title="object&#40;&#123;&#10; allowed_policy_member_domains &#61; list&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | |
| [outputs_location](variables.tf#L177) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable | <code>string</code> | | <code>null</code> | |
| [tag_names](variables.tf#L194) | Customized names for resource management tags. | <code title="object&#40;&#123;&#10; context &#61; string&#10; environment &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code title="&#123;&#10; context &#61; &#34;context&#34;&#10; environment &#61; &#34;environment&#34;&#10;&#125;">&#123;&#8230;&#125;</code> | |
| [team_folders](variables.tf#L211) | Team folders to be created. Format is described in a code comment. | <code title="map&#40;object&#40;&#123;&#10; descriptive_name &#61; string&#10; group_iam &#61; map&#40;list&#40;string&#41;&#41;&#10; impersonation_groups &#61; list&#40;string&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>null</code> | |
## Outputs
| name | description | sensitive | consumers |
|---|---|:---:|---|
| [cicd_repositories](outputs.tf#L145) | WIF configuration for CI/CD repositories. | | |
| [dataplatform](outputs.tf#L159) | Data for the Data Platform stage. | | |
| [networking](outputs.tf#L175) | Data for the networking stage. | | |
| [project_factories](outputs.tf#L184) | Data for the project factories stage. | | |
| [providers](outputs.tf#L200) | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>03-dataplatform</code> · <code>xx-sandbox</code> · <code>xx-teams</code> |
| [sandbox](outputs.tf#L207) | Data for the sandbox stage. | | <code>xx-sandbox</code> |
| [security](outputs.tf#L217) | Data for the networking stage. | | <code>02-security</code> |
| [teams](outputs.tf#L227) | Data for the teams stage. | | |
| [tfvars](outputs.tf#L240) | Terraform variable files for the following stages. | ✓ | |
| [cicd_repositories](outputs.tf#L154) | WIF configuration for CI/CD repositories. | | |
| [dataplatform](outputs.tf#L168) | Data for the Data Platform stage. | | |
| [networking](outputs.tf#L184) | Data for the networking stage. | | |
| [project_factories](outputs.tf#L193) | Data for the project factories stage. | | |
| [providers](outputs.tf#L209) | Terraform provider files for this stage and dependent stages. | ✓ | <code>02-networking</code> · <code>02-security</code> · <code>03-dataplatform</code> · <code>xx-sandbox</code> · <code>xx-teams</code> |
| [sandbox](outputs.tf#L216) | Data for the sandbox stage. | | <code>xx-sandbox</code> |
| [security](outputs.tf#L230) | Data for the networking stage. | | <code>02-security</code> |
| [teams](outputs.tf#L240) | Data for the teams stage. | | |
| [tfvars](outputs.tf#L253) | Terraform variable files for the following stages. | ✓ | |
<!-- END TFDOC -->

View File

@ -16,8 +16,14 @@
# tfdoc:file:description Data Platform stages resources.
moved {
from = module.branch-dp-folder
to = module.branch-dp-folder.0
}
module "branch-dp-folder" {
source = "../../../modules/folder"
count = var.fast_features.data_platform ? 1 : 0
parent = "organizations/${var.organization.id}"
name = "Data Platform"
tag_bindings = {
@ -27,18 +33,26 @@ module "branch-dp-folder" {
}
}
moved {
from = module.branch-dp-dev-folder
to = module.branch-dp-dev-folder.0
}
module "branch-dp-dev-folder" {
source = "../../../modules/folder"
parent = module.branch-dp-folder.id
count = var.fast_features.data_platform ? 1 : 0
parent = module.branch-dp-folder.0.id
name = "Development"
group_iam = {}
iam = {
(local.custom_roles.service_project_network_admin) = [module.branch-dp-dev-sa.iam_email]
(local.custom_roles.service_project_network_admin) = [
module.branch-dp-dev-sa.0.iam_email
]
# remove owner here and at project level if SA does not manage project resources
"roles/owner" = [module.branch-dp-dev-sa.iam_email]
"roles/logging.admin" = [module.branch-dp-dev-sa.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-dp-dev-sa.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-dp-dev-sa.iam_email]
"roles/owner" = [module.branch-dp-dev-sa.0.iam_email]
"roles/logging.admin" = [module.branch-dp-dev-sa.0.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-dp-dev-sa.0.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-dp-dev-sa.0.iam_email]
}
tag_bindings = {
context = try(
@ -47,18 +61,24 @@ module "branch-dp-dev-folder" {
}
}
moved {
from = module.branch-dp-prod-folder
to = module.branch-dp-prod-folder.0
}
module "branch-dp-prod-folder" {
source = "../../../modules/folder"
parent = module.branch-dp-folder.id
count = var.fast_features.data_platform ? 1 : 0
parent = module.branch-dp-folder.0.id
name = "Production"
group_iam = {}
iam = {
(local.custom_roles.service_project_network_admin) = [module.branch-dp-prod-sa.iam_email]
(local.custom_roles.service_project_network_admin) = [module.branch-dp-prod-sa.0.iam_email]
# remove owner here and at project level if SA does not manage project resources
"roles/owner" = [module.branch-dp-prod-sa.iam_email]
"roles/logging.admin" = [module.branch-dp-prod-sa.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-dp-prod-sa.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-dp-prod-sa.iam_email]
"roles/owner" = [module.branch-dp-prod-sa.0.iam_email]
"roles/logging.admin" = [module.branch-dp-prod-sa.0.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-dp-prod-sa.0.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-dp-prod-sa.0.iam_email]
}
tag_bindings = {
context = try(
@ -69,8 +89,14 @@ module "branch-dp-prod-folder" {
# automation service accounts and buckets
moved {
from = module.branch-dp-dev-sa
to = module.branch-dp-dev-sa.0
}
module "branch-dp-dev-sa" {
source = "../../../modules/iam-service-account"
count = var.fast_features.data_platform ? 1 : 0
project_id = var.automation.project_id
name = "dev-resman-dp-0"
description = "Terraform data platform development service account."
@ -85,8 +111,14 @@ module "branch-dp-dev-sa" {
}
}
moved {
from = module.branch-dp-prod-sa
to = module.branch-dp-prod-sa.0
}
module "branch-dp-prod-sa" {
source = "../../../modules/iam-service-account"
count = var.fast_features.data_platform ? 1 : 0
project_id = var.automation.project_id
name = "prod-resman-dp-0"
description = "Terraform data platform production service account."
@ -101,24 +133,36 @@ module "branch-dp-prod-sa" {
}
}
moved {
from = module.branch-dp-dev-gcs
to = module.branch-dp-dev-gcs.0
}
module "branch-dp-dev-gcs" {
source = "../../../modules/gcs"
count = var.fast_features.data_platform ? 1 : 0
project_id = var.automation.project_id
name = "dev-resman-dp-0"
prefix = var.prefix
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-dp-dev-sa.iam_email]
"roles/storage.objectAdmin" = [module.branch-dp-dev-sa.0.iam_email]
}
}
moved {
from = module.branch-dp-prod-gcs
to = module.branch-dp-prod-gcs.0
}
module "branch-dp-prod-gcs" {
source = "../../../modules/gcs"
count = var.fast_features.data_platform ? 1 : 0
project_id = var.automation.project_id
name = "prod-resman-dp-0"
prefix = var.prefix
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-dp-prod-sa.iam_email]
"roles/storage.objectAdmin" = [module.branch-dp-prod-sa.0.iam_email]
}
}

View File

@ -50,10 +50,10 @@ module "branch-network-prod-folder" {
parent = module.branch-network-folder.id
name = "Production"
iam = {
"roles/compute.xpnAdmin" = [
module.branch-dp-prod-sa.iam_email,
module.branch-teams-prod-pf-sa.iam_email
]
"roles/compute.xpnAdmin" = compact([
try(module.branch-dp-prod-sa.0.iam_email, ""),
try(module.branch-pf-prod-sa.0.iam_email, ""),
])
}
tag_bindings = {
environment = try(
@ -67,10 +67,10 @@ module "branch-network-dev-folder" {
parent = module.branch-network-folder.id
name = "Development"
iam = {
(local.custom_roles.service_project_network_admin) = [
module.branch-dp-dev-sa.iam_email,
module.branch-teams-dev-pf-sa.iam_email
]
(local.custom_roles.service_project_network_admin) = compact([
try(module.branch-dp-dev-sa.0.iam_email, ""),
try(module.branch-pf-dev-sa.0.iam_email, ""),
])
}
tag_bindings = {
environment = try(

View File

@ -0,0 +1,97 @@
/**
* 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 stage resources.
moved {
from = module.branch-teams-dev-pf-sa
to = module.branch-pf-dev-sa.0
}
module "branch-pf-dev-sa" {
source = "../../../modules/iam-service-account"
count = var.fast_features.project_factory ? 1 : 0
project_id = var.automation.project_id
name = "dev-resman-pf-0"
# naming: environment in description
description = "Terraform project factory development service account."
prefix = var.prefix
iam = {
"roles/iam.serviceAccountTokenCreator" = compact([
try(module.branch-pf-dev-sa-cicd.0.iam_email, null)
])
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.admin"]
}
}
moved {
from = module.branch-teams-prod-pf-sa
to = module.branch-pf-prod-sa.0
}
module "branch-pf-prod-sa" {
source = "../../../modules/iam-service-account"
count = var.fast_features.project_factory ? 1 : 0
project_id = var.automation.project_id
name = "prod-resman-pf-0"
# naming: environment in description
description = "Terraform project factory production service account."
prefix = var.prefix
iam = {
"roles/iam.serviceAccountTokenCreator" = compact([
try(module.branch-pf-prod-sa-cicd.0.iam_email, null)
])
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.admin"]
}
}
moved {
from = module.branch-teams-dev-pf-gcs
to = module.branch-pf-dev-gcs.0
}
module "branch-pf-dev-gcs" {
source = "../../../modules/gcs"
count = var.fast_features.project_factory ? 1 : 0
project_id = var.automation.project_id
name = "dev-resman-pf-0"
prefix = var.prefix
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-pf-dev-sa.0.iam_email]
}
}
moved {
from = module.branch-teams-prod-pf-gcs
to = module.branch-pf-prod-gcs.0
}
module "branch-pf-prod-gcs" {
source = "../../../modules/gcs"
count = var.fast_features.project_factory ? 1 : 0
project_id = var.automation.project_id
name = "prod-resman-pf-0"
prefix = var.prefix
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-pf-prod-sa.0.iam_email]
}
}

View File

@ -16,15 +16,21 @@
# tfdoc:file:description Sandbox stage resources.
moved {
from = module.branch-sandbox-folder
to = module.branch-sandbox-folder.0
}
module "branch-sandbox-folder" {
source = "../../../modules/folder"
count = var.fast_features.sandbox ? 1 : 0
parent = "organizations/${var.organization.id}"
name = "Sandbox"
iam = {
"roles/logging.admin" = [module.branch-sandbox-sa.iam_email]
"roles/owner" = [module.branch-sandbox-sa.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-sandbox-sa.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-sandbox-sa.iam_email]
"roles/logging.admin" = [module.branch-sandbox-sa.0.iam_email]
"roles/owner" = [module.branch-sandbox-sa.0.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-sandbox-sa.0.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-sandbox-sa.0.iam_email]
}
policy_boolean = {
"constraints/sql.restrictPublicIp" = false
@ -44,19 +50,31 @@ module "branch-sandbox-folder" {
}
}
moved {
from = module.branch-sandbox-gcs
to = module.branch-sandbox-gcs.0
}
module "branch-sandbox-gcs" {
source = "../../../modules/gcs"
count = var.fast_features.sandbox ? 1 : 0
project_id = var.automation.project_id
name = "dev-resman-sbox-0"
prefix = var.prefix
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-sandbox-sa.iam_email]
"roles/storage.objectAdmin" = [module.branch-sandbox-sa.0.iam_email]
}
}
moved {
from = module.branch-sandbox-sa
to = module.branch-sandbox-sa.0
}
module "branch-sandbox-sa" {
source = "../../../modules/iam-service-account"
count = var.fast_features.sandbox ? 1 : 0
project_id = var.automation.project_id
name = "dev-resman-sbox-0"
description = "Terraform resman sandbox service account."

View File

@ -16,8 +16,14 @@
# tfdoc:file:description Team stage resources.
moved {
from = module.branch-teams-folder
to = module.branch-teams-folder.0
}
module "branch-teams-folder" {
source = "../../../modules/folder"
count = var.fast_features.teams ? 1 : 0
parent = "organizations/${var.organization.id}"
name = "Teams"
tag_bindings = {
@ -27,8 +33,14 @@ module "branch-teams-folder" {
}
}
moved {
from = module.branch-teams-prod-sa
to = module.branch-teams-prod-sa.0
}
module "branch-teams-prod-sa" {
source = "../../../modules/iam-service-account"
count = var.fast_features.teams ? 1 : 0
project_id = var.automation.project_id
name = "prod-resman-teams-0"
description = "Terraform resman production service account."
@ -39,15 +51,15 @@ module "branch-teams-prod-sa" {
module "branch-teams-team-folder" {
source = "../../../modules/folder"
for_each = coalesce(var.team_folders, {})
parent = module.branch-teams-folder.id
for_each = var.fast_features.teams ? coalesce(var.team_folders, {}) : {}
parent = module.branch-teams-folder.0.id
name = each.value.descriptive_name
group_iam = each.value.group_iam == null ? {} : each.value.group_iam
}
module "branch-teams-team-sa" {
source = "../../../modules/iam-service-account"
for_each = coalesce(var.team_folders, {})
for_each = var.fast_features.teams ? coalesce(var.team_folders, {}) : {}
project_id = var.automation.project_id
name = "prod-teams-${each.key}-0"
description = "Terraform team ${each.key} service account."
@ -63,7 +75,7 @@ module "branch-teams-team-sa" {
module "branch-teams-team-gcs" {
source = "../../../modules/gcs"
for_each = coalesce(var.team_folders, {})
for_each = var.fast_features.teams ? coalesce(var.team_folders, {}) : {}
project_id = var.automation.project_id
name = "prod-teams-${each.key}-0"
prefix = var.prefix
@ -77,19 +89,19 @@ module "branch-teams-team-gcs" {
module "branch-teams-team-dev-folder" {
source = "../../../modules/folder"
for_each = coalesce(var.team_folders, {})
for_each = var.fast_features.teams ? coalesce(var.team_folders, {}) : {}
parent = module.branch-teams-team-folder[each.key].id
# naming: environment descriptive name
name = "Development"
# environment-wide human permissions on the whole teams environment
group_iam = {}
iam = {
(local.custom_roles.service_project_network_admin) = [module.branch-teams-dev-pf-sa.iam_email]
(local.custom_roles.service_project_network_admin) = [module.branch-pf-dev-sa.0.iam_email]
# remove owner here and at project level if SA does not manage project resources
"roles/owner" = [module.branch-teams-dev-pf-sa.iam_email]
"roles/logging.admin" = [module.branch-teams-dev-pf-sa.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-teams-dev-pf-sa.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-teams-dev-pf-sa.iam_email]
"roles/owner" = [module.branch-pf-dev-sa.0.iam_email]
"roles/logging.admin" = [module.branch-pf-dev-sa.0.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-pf-dev-sa.0.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-pf-dev-sa.0.iam_email]
}
tag_bindings = {
environment = try(
@ -100,19 +112,19 @@ module "branch-teams-team-dev-folder" {
module "branch-teams-team-prod-folder" {
source = "../../../modules/folder"
for_each = coalesce(var.team_folders, {})
for_each = var.fast_features.teams ? coalesce(var.team_folders, {}) : {}
parent = module.branch-teams-team-folder[each.key].id
# naming: environment descriptive name
name = "Production"
# environment-wide human permissions on the whole teams environment
group_iam = {}
iam = {
(local.custom_roles.service_project_network_admin) = [module.branch-teams-prod-pf-sa.iam_email]
(local.custom_roles.service_project_network_admin) = [module.branch-pf-prod-sa.0.iam_email]
# remove owner here and at project level if SA does not manage project resources
"roles/owner" = [module.branch-teams-prod-pf-sa.iam_email]
"roles/logging.admin" = [module.branch-teams-prod-pf-sa.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-teams-prod-pf-sa.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-teams-prod-pf-sa.iam_email]
"roles/owner" = [module.branch-pf-prod-sa.0.iam_email]
"roles/logging.admin" = [module.branch-pf-prod-sa.0.iam_email]
"roles/resourcemanager.folderAdmin" = [module.branch-pf-prod-sa.0.iam_email]
"roles/resourcemanager.projectCreator" = [module.branch-pf-prod-sa.0.iam_email]
}
tag_bindings = {
environment = try(
@ -120,63 +132,3 @@ module "branch-teams-team-prod-folder" {
)
}
}
# project factory per-team environment service accounts
module "branch-teams-dev-pf-sa" {
source = "../../../modules/iam-service-account"
project_id = var.automation.project_id
name = "dev-resman-pf-0"
# naming: environment in description
description = "Terraform project factory development service account."
prefix = var.prefix
iam = {
"roles/iam.serviceAccountTokenCreator" = compact([
try(module.branch-teams-dev-pf-sa-cicd.0.iam_email, null)
])
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.admin"]
}
}
module "branch-teams-prod-pf-sa" {
source = "../../../modules/iam-service-account"
project_id = var.automation.project_id
name = "prod-resman-pf-0"
# naming: environment in description
description = "Terraform project factory production service account."
prefix = var.prefix
iam = {
"roles/iam.serviceAccountTokenCreator" = compact([
try(module.branch-teams-prod-pf-sa-cicd.0.iam_email, null)
])
}
iam_storage_roles = {
(var.automation.outputs_bucket) = ["roles/storage.admin"]
}
}
# project factory per-team environment GCS buckets
module "branch-teams-dev-pf-gcs" {
source = "../../../modules/gcs"
project_id = var.automation.project_id
name = "dev-resman-pf-0"
prefix = var.prefix
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-teams-dev-pf-sa.iam_email]
}
}
module "branch-teams-prod-pf-gcs" {
source = "../../../modules/gcs"
project_id = var.automation.project_id
name = "prod-resman-pf-0"
prefix = var.prefix
versioning = true
iam = {
"roles/storage.objectAdmin" = [module.branch-teams-prod-pf-sa.iam_email]
}
}

View File

@ -28,8 +28,12 @@ module "branch-dp-dev-cicd-repo" {
project_id = var.automation.project_id
name = each.value.name
iam = {
"roles/source.admin" = [module.branch-dp-dev-sa.iam_email]
"roles/source.reader" = [module.branch-dp-dev-sa-cicd.0.iam_email]
"roles/source.admin" = compact([
try(module.branch-dp-dev-sa.0.iam_email, "")
])
"roles/source.reader" = compact([
try(module.branch-dp-dev-sa-cicd.0.iam_email, "")
])
}
triggers = {
fast-03-dp-dev = {
@ -60,7 +64,7 @@ module "branch-dp-prod-cicd-repo" {
project_id = var.automation.project_id
name = each.value.name
iam = {
"roles/source.admin" = [module.branch-dp-prod-sa.iam_email]
"roles/source.admin" = [module.branch-dp-prod-sa.0.iam_email]
"roles/source.reader" = [module.branch-dp-prod-sa-cicd.0.iam_email]
}
triggers = {

View File

@ -18,7 +18,12 @@
# source repositories
module "branch-teams-dev-pf-cicd-repo" {
moved {
from = module.branch-teams-dev-pf-cicd-repo
to = module.branch-pf-dev-cicd-repo
}
module "branch-pf-dev-cicd-repo" {
source = "../../../modules/source-repository"
for_each = (
try(local.cicd_repositories.project_factory_dev.type, null) == "sourcerepo"
@ -28,8 +33,8 @@ module "branch-teams-dev-pf-cicd-repo" {
project_id = var.automation.project_id
name = each.value.name
iam = {
"roles/source.admin" = [module.branch-teams-dev-pf-sa.iam_email]
"roles/source.reader" = [module.branch-teams-dev-pf-sa-cicd.0.iam_email]
"roles/source.admin" = [module.branch-pf-dev-sa.0.iam_email]
"roles/source.reader" = [module.branch-pf-dev-sa-cicd.0.iam_email]
}
triggers = {
fast-03-pf-dev = {
@ -37,7 +42,7 @@ module "branch-teams-dev-pf-cicd-repo" {
included_files = [
"**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml"
]
service_account = module.branch-teams-dev-pf-sa-cicd.0.id
service_account = module.branch-pf-dev-sa-cicd.0.id
substitutions = {}
template = {
project_id = null
@ -47,10 +52,15 @@ module "branch-teams-dev-pf-cicd-repo" {
}
}
}
depends_on = [module.branch-teams-dev-pf-sa-cicd]
depends_on = [module.branch-pf-dev-sa-cicd]
}
module "branch-teams-prod-pf-cicd-repo" {
moved {
from = module.branch-teams-prod-pf-cicd-repo
to = module.branch-pf-prod-cicd-repo
}
module "branch-pf-prod-cicd-repo" {
source = "../../../modules/source-repository"
for_each = (
try(local.cicd_repositories.project_factory_prod.type, null) == "sourcerepo"
@ -60,8 +70,8 @@ module "branch-teams-prod-pf-cicd-repo" {
project_id = var.automation.project_id
name = each.value.name
iam = {
"roles/source.admin" = [module.branch-teams-prod-pf-sa.iam_email]
"roles/source.reader" = [module.branch-teams-prod-pf-sa-cicd.0.iam_email]
"roles/source.admin" = [module.branch-pf-prod-sa.0.iam_email]
"roles/source.reader" = [module.branch-pf-prod-sa-cicd.0.iam_email]
}
triggers = {
fast-03-pf-prod = {
@ -69,7 +79,7 @@ module "branch-teams-prod-pf-cicd-repo" {
included_files = [
"**/*json", "**/*tf", "**/*yaml", ".cloudbuild/workflow.yaml"
]
service_account = module.branch-teams-prod-pf-sa-cicd.0.id
service_account = module.branch-pf-prod-sa-cicd.0.id
substitutions = {}
template = {
project_id = null
@ -79,12 +89,17 @@ module "branch-teams-prod-pf-cicd-repo" {
}
}
}
depends_on = [module.branch-teams-prod-pf-sa-cicd]
depends_on = [module.branch-pf-prod-sa-cicd]
}
# SAs used by CI/CD workflows to impersonate automation SAs
module "branch-teams-dev-pf-sa-cicd" {
moved {
from = module.branch-teams-dev-pf-sa-cicd
to = module.branch-pf-dev-sa-cicd
}
module "branch-pf-dev-sa-cicd" {
source = "../../../modules/iam-service-account"
for_each = (
try(local.cicd_repositories.project_factory_dev.name, null) != null
@ -125,7 +140,12 @@ module "branch-teams-dev-pf-sa-cicd" {
}
}
module "branch-teams-prod-pf-sa-cicd" {
moved {
from = module.branch-teams-prod-pf-sa-cicd
to = module.branch-pf-prod-sa-cicd
}
module "branch-pf-prod-sa-cicd" {
source = "../../../modules/iam-service-account"
for_each = (
try(local.cicd_repositories.project_factory_prod.name, null) != null

View File

@ -18,16 +18,23 @@
locals {
# set to the empty list if you remove the data platform branch
branch_dataplatform_sa_iam_emails = [
module.branch-dp-dev-sa.iam_email,
module.branch-dp-prod-sa.iam_email
]
branch_dataplatform_sa_iam_emails = (
var.fast_features.data_platform
? [
module.branch-dp-dev-sa.0.iam_email,
module.branch-dp-prod-sa.0.iam_email
]
: []
)
# set to the empty list if you remove the teams branch
branch_teams_pf_sa_iam_emails = [
module.branch-teams-dev-pf-sa.iam_email,
module.branch-teams-prod-pf-sa.iam_email
]
branch_teams_pf_sa_iam_emails = (
var.fast_features.project_factory
? [
module.branch-pf-dev-sa.0.iam_email,
module.branch-pf-prod-sa.0.iam_email
]
: []
)
list_allow = {
inherit_from_parent = false
suggested_value = null
@ -176,18 +183,16 @@ module "organization" {
# organization policy admin role assigned with a condition on tags
resource "google_organization_iam_member" "org_policy_admin" {
for_each = {
data-dev = ["data", "development", module.branch-dp-dev-sa.iam_email]
data-prod = ["data", "production", module.branch-dp-prod-sa.iam_email]
pf-dev = ["teams", "development", module.branch-teams-dev-pf-sa.iam_email]
pf-prod = ["teams", "production", module.branch-teams-prod-pf-sa.iam_email]
resource "google_organization_iam_member" "org_policy_admin_dp" {
for_each = !var.fast_features.data_platform ? {} : {
data-dev = ["data", "development", module.branch-dp-dev-sa.0.iam_email]
data-prod = ["data", "production", module.branch-dp-prod-sa.0.iam_email]
}
org_id = var.organization.id
role = "roles/orgpolicy.policyAdmin"
member = each.value.2
condition {
title = "org_policy_tag_scoped"
title = "org_policy_tag_dp_scoped"
description = "Org policy tag scoped grant for ${each.value.0}/${each.value.1}."
expression = <<-END
resource.matchTag('${var.organization.id}/${var.tag_names.context}', '${each.value.0}')
@ -197,3 +202,21 @@ resource "google_organization_iam_member" "org_policy_admin" {
}
}
resource "google_organization_iam_member" "org_policy_admin_pf" {
for_each = !var.fast_features.project_factory ? {} : {
pf-dev = ["teams", "development", module.branch-pf-dev-sa.0.iam_email]
pf-prod = ["teams", "production", module.branch-pf-prod-sa.0.iam_email]
}
org_id = var.organization.id
role = "roles/orgpolicy.policyAdmin"
member = each.value.2
condition {
title = "org_policy_tag_pf_scoped"
description = "Org policy tag scoped grant for ${each.value.0}/${each.value.1}."
expression = <<-END
resource.matchTag('${var.organization.id}/${var.tag_names.context}', '${each.value.0}')
&&
resource.matchTag('${var.organization.id}/${var.tag_names.environment}', '${each.value.1}')
END
}
}

View File

@ -33,12 +33,12 @@ locals {
tf_var_files = local.cicd_workflow_var_files.stage_2
}
project_factory_dev = {
service_account = try(module.branch-teams-dev-pf-sa-cicd.0.email, null)
service_account = try(module.branch-pf-dev-sa-cicd.0.email, null)
tf_providers_file = "03-project-factory-dev-providers.tf"
tf_var_files = local.cicd_workflow_var_files.stage_3
}
project_factory_prod = {
service_account = try(module.branch-teams-prod-pf-sa-cicd.0.email, null)
service_account = try(module.branch-pf-prod-sa-cicd.0.email, null)
tf_providers_file = "03-project-factory-prod-providers.tf"
tf_var_files = local.cicd_workflow_var_files.stage_3
}
@ -62,13 +62,14 @@ locals {
}
folder_ids = merge(
{
data-platform = module.branch-dp-dev-folder.id
networking = module.branch-network-folder.id
networking-dev = module.branch-network-dev-folder.id
networking-prod = module.branch-network-prod-folder.id
sandbox = module.branch-sandbox-folder.id
security = module.branch-security-folder.id
teams = module.branch-teams-folder.id
data-platform-dev = try(module.branch-dp-dev-folder.0.id, null)
data-platform-prod = try(module.branch-dp-prod-folder.0.id, null)
networking = module.branch-network-folder.id
networking-dev = module.branch-network-dev-folder.id
networking-prod = module.branch-network-prod-folder.id
sandbox = try(module.branch-sandbox-folder.0.id, null)
security = module.branch-security-folder.id
teams = try(module.branch-teams-folder.0.id, null)
},
{
for k, v in module.branch-teams-team-folder :
@ -83,53 +84,61 @@ locals {
"team-${k}-prod" => v.id
}
)
providers = {
"02-networking" = templatefile(local._tpl_providers, {
bucket = module.branch-network-gcs.name
name = "networking"
sa = module.branch-network-sa.email
})
"02-security" = templatefile(local._tpl_providers, {
bucket = module.branch-security-gcs.name
name = "security"
sa = module.branch-security-sa.email
})
"03-data-platform-dev" = templatefile(local._tpl_providers, {
bucket = module.branch-dp-dev-gcs.name
name = "dp-dev"
sa = module.branch-dp-dev-sa.email
})
"03-data-platform-prod" = templatefile(local._tpl_providers, {
bucket = module.branch-dp-prod-gcs.name
name = "dp-prod"
sa = module.branch-dp-prod-sa.email
})
"03-project-factory-dev" = templatefile(local._tpl_providers, {
bucket = module.branch-teams-dev-pf-gcs.name
name = "team-dev"
sa = module.branch-teams-dev-pf-sa.email
})
"03-project-factory-prod" = templatefile(local._tpl_providers, {
bucket = module.branch-teams-prod-pf-gcs.name
name = "team-prod"
sa = module.branch-teams-prod-pf-sa.email
})
"99-sandbox" = templatefile(local._tpl_providers, {
bucket = module.branch-sandbox-gcs.name
name = "sandbox"
sa = module.branch-sandbox-sa.email
})
}
providers = merge(
{
"02-networking" = templatefile(local._tpl_providers, {
bucket = module.branch-network-gcs.name
name = "networking"
sa = module.branch-network-sa.email
})
"02-security" = templatefile(local._tpl_providers, {
bucket = module.branch-security-gcs.name
name = "security"
sa = module.branch-security-sa.email
})
},
!var.fast_features.data_platform ? {} : {
"03-data-platform-dev" = templatefile(local._tpl_providers, {
bucket = module.branch-dp-dev-gcs.0.name
name = "dp-dev"
sa = module.branch-dp-dev-sa.0.email
})
"03-data-platform-prod" = templatefile(local._tpl_providers, {
bucket = module.branch-dp-prod-gcs.0.name
name = "dp-prod"
sa = module.branch-dp-prod-sa.0.email
})
},
!var.fast_features.project_factory ? {} : {
"03-project-factory-dev" = templatefile(local._tpl_providers, {
bucket = module.branch-pf-dev-gcs.0.name
name = "team-dev"
sa = module.branch-pf-dev-sa.0.email
})
"03-project-factory-prod" = templatefile(local._tpl_providers, {
bucket = module.branch-pf-prod-gcs.0.name
name = "team-prod"
sa = module.branch-pf-prod-sa.0.email
})
},
!var.fast_features.sandbox ? {} : {
"99-sandbox" = templatefile(local._tpl_providers, {
bucket = module.branch-sandbox-gcs.0.name
name = "sandbox"
sa = module.branch-sandbox-sa.0.email
})
}
)
service_accounts = merge(
{
data-platform-dev = module.branch-dp-dev-sa.email
data-platform-prod = module.branch-dp-prod-sa.email
data-platform-dev = try(module.branch-dp-dev-sa.0.email, null)
data-platform-prod = try(module.branch-dp-prod-sa.0.email, null)
networking = module.branch-network-sa.email
project-factory-dev = module.branch-teams-dev-pf-sa.email
project-factory-prod = module.branch-teams-prod-pf-sa.email
sandbox = module.branch-sandbox-sa.email
project-factory-dev = try(module.branch-pf-dev-sa.0.email, null)
project-factory-prod = try(module.branch-pf-prod-sa.0.email, null)
sandbox = try(module.branch-sandbox-sa.0.email, null)
security = module.branch-security-sa.email
teams = module.branch-teams-prod-sa.email
teams = try(module.branch-teams-prod-sa.0.email, null)
},
{
for k, v in module.branch-teams-team-sa : "team-${k}" => v.email
@ -158,16 +167,16 @@ output "cicd_repositories" {
output "dataplatform" {
description = "Data for the Data Platform stage."
value = {
value = !var.fast_features.data_platform ? {} : {
dev = {
folder = module.branch-dp-dev-folder.id
gcs_bucket = module.branch-dp-dev-gcs.name
service_account = module.branch-dp-dev-sa.email
folder = module.branch-dp-dev-folder.0.id
gcs_bucket = module.branch-dp-dev-gcs.0.name
service_account = module.branch-dp-dev-sa.0.email
}
prod = {
folder = module.branch-dp-prod-folder.id
gcs_bucket = module.branch-dp-prod-gcs.name
service_account = module.branch-dp-prod-sa.email
folder = module.branch-dp-prod-folder.0.id
gcs_bucket = module.branch-dp-prod-gcs.0.name
service_account = module.branch-dp-prod-sa.0.email
}
}
}
@ -183,14 +192,14 @@ output "networking" {
output "project_factories" {
description = "Data for the project factories stage."
value = {
value = !var.fast_features.project_factory ? {} : {
dev = {
bucket = module.branch-teams-dev-pf-gcs.name
sa = module.branch-teams-dev-pf-sa.email
bucket = module.branch-pf-dev-gcs.0.name
sa = module.branch-pf-dev-sa.0.email
}
prod = {
bucket = module.branch-teams-prod-pf-gcs.name
sa = module.branch-teams-prod-pf-sa.email
bucket = module.branch-pf-prod-gcs.0.name
sa = module.branch-pf-prod-sa.0.email
}
}
}
@ -207,11 +216,15 @@ output "providers" {
output "sandbox" {
# tfdoc:output:consumers xx-sandbox
description = "Data for the sandbox stage."
value = {
folder = module.branch-sandbox-folder.id
gcs_bucket = module.branch-sandbox-gcs.name
service_account = module.branch-sandbox-sa.email
}
value = (
var.fast_features.sandbox
? {
folder = module.branch-sandbox-folder.0.id
gcs_bucket = module.branch-sandbox-gcs.0.name
service_account = module.branch-sandbox-sa.0.email
}
: null
)
}
output "security" {

View File

@ -123,6 +123,24 @@ variable "custom_roles" {
default = null
}
variable "fast_features" {
# tfdoc:variable:source 00-bootstrap
description = "Selective control for top-level FAST features."
type = object({
data_platform = bool
project_factory = bool
sandbox = bool
teams = bool
})
default = {
data_platform = true
project_factory = true
sandbox = true
teams = true
}
# nullable = false
}
variable "groups" {
# tfdoc:variable:source 00-bootstrap
description = "Group names to grant organization-level permissions."

View File

@ -40,7 +40,7 @@ module "dev-spoke-project" {
}
metric_scopes = [module.landing-project.project_id]
iam = {
"roles/dns.admin" = [local.service_accounts.project-factory-dev]
"roles/dns.admin" = compact([local.service_accounts.project-factory-dev])
}
}
@ -123,10 +123,10 @@ module "peering-dev" {
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = [
members = compact([
local.service_accounts.data-platform-dev,
local.service_accounts.project-factory-dev,
]
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."

View File

@ -40,7 +40,7 @@ module "prod-spoke-project" {
}
metric_scopes = [module.landing-project.project_id]
iam = {
"roles/dns.admin" = [local.service_accounts.project-factory-prod]
"roles/dns.admin" = compact([local.service_accounts.project-factory-prod])
}
}
@ -123,10 +123,10 @@ module "peering-prod" {
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = [
members = compact([
local.service_accounts.data-platform-prod,
local.service_accounts.project-factory-prod,
]
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."

View File

@ -41,7 +41,7 @@ module "dev-spoke-project" {
}
metric_scopes = [module.landing-project.project_id]
iam = {
"roles/dns.admin" = [local.service_accounts.project-factory-dev]
"roles/dns.admin" = compact([local.service_accounts.project-factory-dev])
}
}
@ -100,10 +100,10 @@ module "dev-spoke-cloudnat" {
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = [
members = compact([
local.service_accounts.data-platform-dev,
local.service_accounts.project-factory-dev,
]
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."

View File

@ -41,7 +41,7 @@ module "prod-spoke-project" {
}
metric_scopes = [module.landing-project.project_id]
iam = {
"roles/dns.admin" = [local.service_accounts.project-factory-prod]
"roles/dns.admin" = compact([local.service_accounts.project-factory-prod])
}
}
@ -100,10 +100,10 @@ module "prod-spoke-cloudnat" {
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = [
members = compact([
local.service_accounts.data-platform-prod,
local.service_accounts.project-factory-prod,
]
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."

View File

@ -41,7 +41,7 @@ module "dev-spoke-project" {
}
metric_scopes = [module.landing-project.project_id]
iam = {
"roles/dns.admin" = [local.service_accounts.project-factory-dev]
"roles/dns.admin" = compact([local.service_accounts.project-factory-dev])
}
}
@ -100,10 +100,10 @@ module "dev-spoke-cloudnat" {
resource "google_project_iam_binding" "dev_spoke_project_iam_delegated" {
project = module.dev-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = [
members = compact([
local.service_accounts.data-platform-dev,
local.service_accounts.project-factory-dev,
]
])
condition {
title = "dev_stage3_sa_delegated_grants"
description = "Development host project delegated grants."

View File

@ -41,7 +41,7 @@ module "prod-spoke-project" {
}
metric_scopes = [module.landing-project.project_id]
iam = {
"roles/dns.admin" = [local.service_accounts.project-factory-prod]
"roles/dns.admin" = compact([local.service_accounts.project-factory-prod])
}
}
@ -100,10 +100,10 @@ module "prod-spoke-cloudnat" {
resource "google_project_iam_binding" "prod_spoke_project_iam_delegated" {
project = module.prod-spoke-project.project_id
role = "roles/resourcemanager.projectIamAdmin"
members = [
members = compact([
local.service_accounts.data-platform-prod,
local.service_accounts.project-factory-prod,
]
])
condition {
title = "prod_stage3_sa_delegated_grants"
description = "Production host project delegated grants."

View File

@ -16,8 +16,10 @@
locals {
dev_kms_restricted_admins = [
"serviceAccount:${var.service_accounts.project-factory-dev}",
"serviceAccount:${var.service_accounts.data-platform-dev}"
for sa in compact([
var.service_accounts.project-factory-dev,
var.service_accounts.data-platform-dev
]) : "serviceAccount:${sa}"
]
}

View File

@ -16,8 +16,10 @@
locals {
prod_kms_restricted_admins = [
"serviceAccount:${var.service_accounts.project-factory-prod}",
"serviceAccount:${var.service_accounts.data-platform-prod}"
for sa in compact([
var.service_accounts.project-factory-prod,
var.service_accounts.data-platform-prod
]) : "serviceAccount:${sa}"
]
}