fix: Multi-tenant parameters from upstream bootstrap (#3265)

* fix: Multi-tenant parameters from upstream bootstrap

* Delint

* fix tests, tfdoc

---------

Co-authored-by: Ludovico Magnocavallo <ludomagno@google.com>
This commit is contained in:
Matt
2025-08-08 02:35:32 -04:00
committed by GitHub
parent 9ad0d57bd2
commit 1b4dcd5b07
5 changed files with 45 additions and 17 deletions

View File

@@ -328,14 +328,14 @@ gcloud storage cp gs://{prefix}-{tenant-shortname}-prod-iac-core-0/tfvars/0-boot
|---|---|:---:|:---:|:---:|:---:|
| [automation](variables-fast.tf#L19) | 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; audiences &#61; list&#40;string&#41;&#10; issuer &#61; string&#10; issuer_uri &#61; string&#10; name &#61; string&#10; principal_branch &#61; string&#10; principal_repo &#61; string&#10; &#125;&#41;&#41;&#10; service_accounts &#61; object&#40;&#123;&#10; resman &#61; string&#10; resman-r &#61; string&#10; &#125;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [billing_account](variables-fast.tf#L42) | Billing account id. If billing account is not part of the same org set `is_org_level` to `false`. To disable handling of billing IAM roles set `no_iam` to `true`. | <code title="object&#40;&#123;&#10; id &#61; string&#10; is_org_level &#61; optional&#40;bool, true&#41;&#10; no_iam &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [environments](variables-fast.tf#L69) | Environment names. | <code title="map&#40;object&#40;&#123;&#10; name &#61; string&#10; short_name &#61; string&#10; tag_name &#61; string&#10; is_default &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | ✓ | | <code>0-globals</code> |
| [logging](variables-fast.tf#L115) | Logging resources created by the bootstrap stage. | <code title="object&#40;&#123;&#10; project_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [org_policy_tags](variables-fast.tf#L134) | Organization policy tags. | <code title="object&#40;&#123;&#10; key_id &#61; string&#10; key_name &#61; string&#10; values &#61; map&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [organization](variables-fast.tf#L124) | 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>0-bootstrap</code> |
| [prefix](variables-fast.tf#L151) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; gcve_network_admin &#61; string&#10; network_firewall_policies_admin &#61; string&#10; ngfw_enterprise_admin &#61; optional&#40;string&#41;&#10; ngfw_enterprise_viewer &#61; optional&#40;string&#41;&#10; organization_admin_viewer &#61; string&#10; service_project_network_admin &#61; string&#10; storage_viewer &#61; string&#10; tenant_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [groups](variables-fast.tf#L87) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object&#40;&#123;&#10; gcp-billing-admins &#61; optional&#40;string, &#34;gcp-billing-admins&#34;&#41;&#10; gcp-devops &#61; optional&#40;string, &#34;gcp-devops&#34;&#41;&#10; gcp-network-admins &#61; optional&#40;string, &#34;gcp-vpc-network-admins&#34;&#41;&#10; gcp-organization-admins &#61; optional&#40;string, &#34;gcp-organization-admins&#34;&#41;&#10; gcp-security-admins &#61; optional&#40;string, &#34;gcp-security-admins&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [locations](variables-fast.tf#L102) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object&#40;&#123;&#10; bq &#61; optional&#40;string, &#34;EU&#34;&#41;&#10; gcs &#61; optional&#40;string, &#34;EU&#34;&#41;&#10; logging &#61; optional&#40;string, &#34;global&#34;&#41;&#10; pubsub &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [environments](variables-fast.tf#L75) | Environment names. | <code title="map&#40;object&#40;&#123;&#10; name &#61; string&#10; short_name &#61; string&#10; tag_name &#61; string&#10; is_default &#61; optional&#40;bool, false&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | ✓ | | <code>0-globals</code> |
| [logging](variables-fast.tf#L121) | Logging resources created by the bootstrap stage. | <code title="object&#40;&#123;&#10; project_id &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [org_policy_tags](variables-fast.tf#L140) | Organization policy tags. | <code title="object&#40;&#123;&#10; key_id &#61; string&#10; key_name &#61; string&#10; values &#61; map&#40;string&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | | <code>0-bootstrap</code> |
| [organization](variables-fast.tf#L130) | 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>0-bootstrap</code> |
| [prefix](variables-fast.tf#L157) | Prefix used for resources that need unique names. Use 9 characters or less. | <code>string</code> | ✓ | | <code>0-bootstrap</code> |
| [custom_roles](variables-fast.tf#L53) | Custom roles defined at the org level, in key => id format. | <code title="object&#40;&#123;&#10; billing_viewer &#61; string&#10; dns_zone_binder &#61; string&#10; kms_key_encryption_admin &#61; string&#10; kms_key_viewer &#61; string&#10; organization_admin_viewer &#61; string&#10; project_iam_viewer &#61; string&#10; service_project_network_admin &#61; string&#10; storage_viewer &#61; string&#10; gcve_network_admin &#61; optional&#40;string&#41;&#10; gcve_network_viewer &#61; optional&#40;string&#41;&#10; network_firewall_policies_admin &#61; optional&#40;string&#41;&#10; ngfw_enterprise_admin &#61; optional&#40;string&#41;&#10; ngfw_enterprise_viewer &#61; optional&#40;string&#41;&#10; tenant_network_admin &#61; string&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-bootstrap</code> |
| [groups](variables-fast.tf#L93) | Group names or IAM-format principals to grant organization-level permissions. If just the name is provided, the 'group:' principal and organization domain are interpolated. | <code title="object&#40;&#123;&#10; gcp-billing-admins &#61; optional&#40;string, &#34;gcp-billing-admins&#34;&#41;&#10; gcp-devops &#61; optional&#40;string, &#34;gcp-devops&#34;&#41;&#10; gcp-network-admins &#61; optional&#40;string, &#34;gcp-vpc-network-admins&#34;&#41;&#10; gcp-organization-admins &#61; optional&#40;string, &#34;gcp-organization-admins&#34;&#41;&#10; gcp-security-admins &#61; optional&#40;string, &#34;gcp-security-admins&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [locations](variables-fast.tf#L108) | Optional locations for GCS, BigQuery, and logging buckets created here. | <code title="object&#40;&#123;&#10; bq &#61; optional&#40;string, &#34;EU&#34;&#41;&#10; gcs &#61; optional&#40;string, &#34;EU&#34;&#41;&#10; logging &#61; optional&#40;string, &#34;global&#34;&#41;&#10; pubsub &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-bootstrap</code> |
| [names](variables.tf#L18) | Configuration for names used for resources and output files. | <code title="object&#40;&#123;&#10; output_files_prefix &#61; optional&#40;string, &#34;2-resman-tenants&#34;&#41;&#10; resource_short_name &#61; optional&#40;string, &#34;tn&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [outputs_location](variables.tf#L28) | Path where providers and tfvars files for the following stages are written. Leave empty to disable. | <code>string</code> | | <code>null</code> | |
| [root_node](variables.tf#L34) | Root folder under which tenants are created, in folders/nnnn format. Defaults to the organization if null. | <code>string</code> | | <code>null</code> | |
@@ -346,5 +346,5 @@ gcloud storage cp gs://{prefix}-{tenant-shortname}-prod-iac-core-0/tfvars/0-boot
| name | description | sensitive | consumers |
|---|---|:---:|---|
| [tenants](outputs.tf#L130) | Tenant base configuration. | | |
| [tenants](outputs.tf#L139) | Tenant base configuration. | | |
<!-- END TFDOC -->

View File

@@ -71,9 +71,18 @@ locals {
for k, v in local.fast_tenants : k => {
billing_account = v.billing_account
groups = v.principals
locations = v.locations
organization = v.organization
prefix = v.prefix
environments = {
for k, v in var.environments : k => {
is_default = v.is_default
key = k
name = v.name
short_name = v.short_name != null ? v.short_name : k
tag_name = v.tag_name != null ? v.tag_name : lower(v.name)
}
}
locations = v.locations
organization = v.organization
prefix = v.prefix
}
}
tenant_tfvars = {

View File

@@ -54,13 +54,19 @@ variable "custom_roles" {
# tfdoc:variable:source 0-bootstrap
description = "Custom roles defined at the org level, in key => id format."
type = object({
gcve_network_admin = string
network_firewall_policies_admin = string
ngfw_enterprise_admin = optional(string)
ngfw_enterprise_viewer = optional(string)
billing_viewer = string
dns_zone_binder = string
kms_key_encryption_admin = string
kms_key_viewer = string
organization_admin_viewer = string
project_iam_viewer = string
service_project_network_admin = string
storage_viewer = string
gcve_network_admin = optional(string)
gcve_network_viewer = optional(string)
network_firewall_policies_admin = optional(string)
ngfw_enterprise_admin = optional(string)
ngfw_enterprise_viewer = optional(string)
tenant_network_admin = string
})
default = null

View File

@@ -20,7 +20,13 @@ module "root-folder" {
id = var.root_node
folder_create = false
# additive bindings via delegated IAM grant set in stage 0
iam_bindings_additive = local.iam_bindings_additive
iam_bindings_additive = {
for k, v in local.iam_bindings_additive : k => {
role = lookup(var.custom_roles, v.role, v.role)
member = lookup(local.principals_iam, v.member, v.member)
condition = lookup(v, "condition", null)
}
}
logging_sinks = {
for name, attrs in local.log_sinks : name => {
bq_partitioned_table = attrs.type == "bigquery"