diff --git a/fast/stages/1-resman/README.md b/fast/stages/1-resman/README.md index c867b2308..0bbb2f81f 100644 --- a/fast/stages/1-resman/README.md +++ b/fast/stages/1-resman/README.md @@ -269,7 +269,7 @@ terraform apply | [environments](variables-fast.tf#L72) | Environment names. | map(object({…})) | ✓ | | 0-globals | | [logging](variables-fast.tf#L118) | Logging configuration for tenants. | object({…}) | ✓ | | 1-tenant-factory | | [organization](variables-fast.tf#L131) | Organization details. | object({…}) | ✓ | | 0-bootstrap | -| [prefix](variables-fast.tf#L149) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap | +| [prefix](variables-fast.tf#L161) | Prefix used for resources that need unique names. Use 9 characters or less. | string | ✓ | | 0-bootstrap | | [custom_roles](variables-fast.tf#L54) | Custom roles defined at the org level, in key => id format. | object({…}) | | null | 0-bootstrap | | [factories_config](variables.tf#L20) | Configuration for the resource factories or external data. | object({…}) | | {} | | | [fast_addon](variables-addons.tf#L17) | FAST addons configurations for stages 2. Keys are used as short names for the add-on resources. | map(object({…})) | | {} | | @@ -277,11 +277,12 @@ terraform apply | [fast_stage_3](variables-stages.tf#L113) | FAST stages 3 configurations. | map(object({…})) | | {} | | | [groups](variables-fast.tf#L90) | 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. | object({…}) | | {} | 0-bootstrap | | [locations](variables-fast.tf#L105) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {} | 0-bootstrap | +| [org_policy_tags](variables-fast.tf#L149) | Organization policy tags. | object({…}) | | {} | 0-bootstrap | | [outputs_location](variables.tf#L31) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | | [resource_names](variables.tf#L37) | Resource names overrides for specific resources. Stage names are interpolated via `$${name}`. Prefix is always set via code, except where noted in the variable type. | object({…}) | | {} | | -| [root_node](variables-fast.tf#L155) | Root node for the hierarchy, if running in tenant mode. | string | | null | 0-bootstrap | +| [root_node](variables-fast.tf#L167) | Root node for the hierarchy, if running in tenant mode. | string | | null | 0-bootstrap | | [tag_names](variables.tf#L57) | Customized names for resource management tags. | object({…}) | | {} | | -| [tags](variables.tf#L71) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | | +| [tags](variables.tf#L71) | Custom secure tags by key name. The `iam` attribute behaves like the similarly named one at module level. | map(object({…})) | | {} | | | [top_level_folders](variables-toplevel-folders.tf#L17) | Additional top-level folders. Keys are used for service account and bucket names, values implement the folders module interface with the addition of the 'automation' attribute. | map(object({…})) | | {} | | ## Outputs diff --git a/fast/stages/1-resman/organization.tf b/fast/stages/1-resman/organization.tf index 3927e13d3..953234b03 100644 --- a/fast/stages/1-resman/organization.tf +++ b/fast/stages/1-resman/organization.tf @@ -72,6 +72,10 @@ locals { ]...), local.billing_mode != "org" ? {} : local.billing_iam ) + org_policy_tags = { + for k, v in var.org_policy_tags.values : + "${var.org_policy_tags.key_name}/${k}" => v + } # IAM principal expansion for user-specified tag values tags = { for k, v in var.tags : k => merge(v, { @@ -80,6 +84,11 @@ locals { for rm in rv : lookup(local.principals_iam, rm, rm) ] } + id = ( + v.id == null || v.id != var.org_policy_tags.key_name + ? v.id + : var.org_policy_tags.key_id + ) values = { for vk, vv in v.values : vk => merge(vv, { iam = { @@ -87,6 +96,9 @@ locals { for rm in rv : lookup(local.principals_iam, rm, rm) ] } + id = ( + vv.id == null ? null : lookup(local.org_policy_tags, vv.id, vv.id) + ) }) } }) diff --git a/fast/stages/1-resman/variables-fast.tf b/fast/stages/1-resman/variables-fast.tf index 439139b84..d35c24a48 100644 --- a/fast/stages/1-resman/variables-fast.tf +++ b/fast/stages/1-resman/variables-fast.tf @@ -146,6 +146,18 @@ check "prefix_validator" { } } +variable "org_policy_tags" { + # tfdoc:variable:source 0-bootstrap + description = "Organization policy tags." + type = object({ + key_id = optional(string) + key_name = optional(string, "org-policies") + values = optional(map(string), {}) + }) + nullable = false + default = {} +} + variable "prefix" { # tfdoc:variable:source 0-bootstrap description = "Prefix used for resources that need unique names. Use 9 characters or less." diff --git a/fast/stages/1-resman/variables.tf b/fast/stages/1-resman/variables.tf index 37ab5325f..5bdf85ee1 100644 --- a/fast/stages/1-resman/variables.tf +++ b/fast/stages/1-resman/variables.tf @@ -73,6 +73,7 @@ variable "tags" { type = map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) + id = optional(string) values = optional(map(object({ description = optional(string, "Managed by the Terraform organization module.") iam = optional(map(list(string)), {}) diff --git a/fast/stages/2-project-factory/README.md b/fast/stages/2-project-factory/README.md index cbe55e472..73b8a4d85 100644 --- a/fast/stages/2-project-factory/README.md +++ b/fast/stages/2-project-factory/README.md @@ -354,17 +354,18 @@ The approach is not shown here but reasonably easy to implement. The main projec |---|---|:---:|:---:|:---:|:---:| | [automation](variables-fast.tf#L17) | Automation resources created by the bootstrap stage. | object({…}) | ✓ | | 0-bootstrap | | [billing_account](variables-fast.tf#L26) | Billing account id. If billing account is not part of the same org set `is_org_level` to false. | object({…}) | ✓ | | 0-bootstrap | -| [prefix](variables-fast.tf#L82) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | 0-bootstrap | +| [prefix](variables-fast.tf#L93) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | string | ✓ | | 0-bootstrap | | [factories_config](variables.tf#L17) | Configuration for YAML-based factories. | object({…}) | | {} | | | [folder_ids](variables-fast.tf#L39) | Folders created in the resource management stage. | map(string) | | {} | 1-resman | | [groups](variables-fast.tf#L47) | 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. | map(string) | | {} | 0-bootstrap | | [host_project_ids](variables-fast.tf#L56) | Host project for the shared VPC. | map(string) | | {} | 2-networking | | [locations](variables-fast.tf#L64) | Optional locations for GCS, BigQuery, and logging buckets created here. | object({…}) | | {} | 0-bootstrap | +| [org_policy_tags](variables-fast.tf#L82) | Optional organization policy tag values. | object({…}) | | {} | 0-bootstrap | | [outputs_location](variables.tf#L39) | Enable writing provider, tfvars and CI/CD workflow files to local filesystem. Leave null to disable. | string | | null | | | [perimeters](variables-fast.tf#L74) | Optional VPC-SC perimeter ids. | map(string) | | {} | 1-vpcsc | -| [service_accounts](variables-fast.tf#L92) | Automation service accounts in name => email format. | map(string) | | {} | 1-resman | +| [service_accounts](variables-fast.tf#L103) | Automation service accounts in name => email format. | map(string) | | {} | 1-resman | | [stage_name](variables.tf#L45) | FAST stage name. Used to separate output files across different factories. | string | | "2-project-factory" | | -| [tag_values](variables-fast.tf#L100) | FAST-managed resource manager tag values. | map(string) | | {} | 1-resman | +| [tag_values](variables-fast.tf#L111) | FAST-managed resource manager tag values. | map(string) | | {} | 1-resman | ## Outputs diff --git a/fast/stages/2-project-factory/main.tf b/fast/stages/2-project-factory/main.tf index eccc0e428..c811e06df 100644 --- a/fast/stages/2-project-factory/main.tf +++ b/fast/stages/2-project-factory/main.tf @@ -47,6 +47,10 @@ module "projects" { ) perimeters = var.perimeters tag_values = merge( + { + for k, v in var.org_policy_tags.values : + "${var.org_policy_tags.key_name}/${k}" => v + }, var.tag_values, var.factories_config.context.tag_values ) diff --git a/fast/stages/2-project-factory/variables-fast.tf b/fast/stages/2-project-factory/variables-fast.tf index bf2d1c9a1..0f99ddbe4 100644 --- a/fast/stages/2-project-factory/variables-fast.tf +++ b/fast/stages/2-project-factory/variables-fast.tf @@ -79,6 +79,17 @@ variable "perimeters" { default = {} } +variable "org_policy_tags" { + # tfdoc:variable:source 0-bootstrap + description = "Optional organization policy tag values." + type = object({ + key_name = optional(string, "org-policies") + values = optional(map(string), {}) + }) + nullable = false + default = {} +} + variable "prefix" { # tfdoc:variable:source 0-bootstrap description = "Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants." diff --git a/modules/project-factory/README.md b/modules/project-factory/README.md index edc48991e..8165d0697 100644 --- a/modules/project-factory/README.md +++ b/modules/project-factory/README.md @@ -494,7 +494,7 @@ service_accounts: | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [factories_config](variables.tf#L121) | Path to folder with YAML resource description data files. | object({…}) | ✓ | | +| [factories_config](variables.tf#L121) | Path to folder with YAML resource description data files. | object({…}) | ✓ | | | [data_defaults](variables.tf#L17) | Optional default values used when corresponding project data from files are missing. | object({…}) | | {} | | [data_merges](variables.tf#L64) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | object({…}) | | {} | | [data_overrides](variables.tf#L83) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | object({…}) | | {} |