Fix regressions in FAST v55.2.0 (#3910)

* fix org-setup outputs

* start work on trickling down tag_vars through stages

* fixes

* tflint

* fix vpn context in fast networking stage

* automated review fixes

* review comments
This commit is contained in:
Ludovico Magnocavallo
2026-04-27 09:01:03 +02:00
committed by GitHub
parent 392ee6bda4
commit b069b67909
16 changed files with 146 additions and 85 deletions

View File

@@ -40,11 +40,26 @@ locals {
module.factory.project_ids
)
storage_buckets = module.factory.storage_buckets
tag_keys = module.organization[0].tag_keys
tag_keys = merge(
local.ctx.tag_keys,
local.org_tag_keys
)
tag_values = merge(
local.ctx.tag_values,
local.org_tag_values
)
tag_vars = {
projects = merge([
for k, v in module.factory.projects : {
(k) = { for kk, vv in v.tag_vars : kk => vv }
} if length(v.tag_vars) > 0
]...)
organization = {
for k, v in module.organization[0].tag_keys :
# the provider returns allowed_values_regex set to "" not null
k => v.namespaced_name if try(v.allowed_values_regex, "") != ""
}
}
})
of_logging_sinks = {
# Include project_id in the destination if supported (omitted for
@@ -128,6 +143,7 @@ locals {
}
tag_keys = local.of_ctx.tag_keys
tag_values = local.of_ctx.tag_values
tag_vars = local.of_ctx.tag_vars
vpc_self_links = {
for k, v in module.vpcs.vpcs : k => v.id
}

View File

@@ -384,7 +384,7 @@ Internally created resources are mapped to context namespaces, and use specific
| [prefix](variables-fast.tf#L75) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | |
| [context](variables.tf#L17) | Context-specific interpolations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [custom_roles](variables-fast.tf#L25) | Custom roles defined at the org level, in key => id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L37) | Configuration for the resource factories or external data. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [factories_config](variables.tf#L41) | Configuration for the resource factories or external data. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [folder_ids](variables-fast.tf#L33) | Folders created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_principals](variables-fast.tf#L41) | IAM-format principals. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [kms_keys](variables-fast.tf#L50) | KMS key ids. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
@@ -392,9 +392,10 @@ Internally created resources are mapped to context namespaces, and use specific
| [project_ids](variables-fast.tf#L85) | Projects created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [service_accounts](variables-fast.tf#L93) | Service accounts created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [storage_buckets](variables-fast.tf#L101) | Storage buckets created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_keys](variables-fast.tf#L109) | FAST-managed resource manager tag keys. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_values](variables-fast.tf#L120) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [universe](variables-fast.tf#L128) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
| [tag_keys](variables-fast.tf#L109) | FAST-managed resource manager tag keys. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_values](variables-fast.tf#L117) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> |
| [tag_vars](variables-fast.tf#L125) | FAST-managed resource manager tag key namespaced names. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> |
| [universe](variables-fast.tf#L136) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> |
## Outputs

View File

@@ -107,7 +107,7 @@ module "vpn-ha" {
}
context = {
locations = local.ctx.locations
network = local.ctx_vpcs.names
networks = local.ctx_vpcs.names
project_ids = local.ctx_projects.project_ids
routers = local.ctx_routers.names
vpn_gateways = local.ctx_gateways

View File

@@ -48,11 +48,12 @@ locals {
tag_keys = merge(var.tag_keys, local._ctx.tag_keys)
tag_values = merge(var.tag_values, local._ctx.tag_values)
tag_vars = {
projects = try(local._ctx.tag_vars.projects, {})
organization = merge({
for k, v in var.tag_keys : k => v.namespaced_name
if v.allowed_values_regex != null
}, try(local._ctx.tag_vars.organization, {}))
organization = merge(
var.tag_vars.organization, local._ctx.tag_vars.organization
)
projects = merge(
var.tag_vars.projects, local._ctx.tag_vars.projects
)
}
vpc_sc_perimeters = merge(var.perimeters, local._ctx.vpc_sc_perimeters)
})

View File

@@ -109,12 +109,9 @@ variable "storage_buckets" {
variable "tag_keys" {
# tfdoc:variable:source 0-org-setup
description = "FAST-managed resource manager tag keys."
type = map(object({
namespaced_name = string
allowed_values_regex = optional(string)
}))
default = {}
nullable = false
type = map(string)
nullable = false
default = {}
}
variable "tag_values" {
@@ -125,6 +122,17 @@ variable "tag_values" {
default = {}
}
variable "tag_vars" {
# tfdoc:variable:source 0-org-setup
description = "FAST-managed resource manager tag key namespaced names."
type = object({
projects = optional(map(map(string)), {})
organization = optional(map(string), {})
})
nullable = false
default = {}
}
variable "universe" {
# tfdoc:variable:source 0-org-setup
description = "GCP universe where to deploy projects. The prefix will be prepended to the project id."

View File

@@ -17,17 +17,21 @@
variable "context" {
description = "Context-specific interpolations."
type = object({
cidr_ranges_sets = optional(map(list(string)), {})
custom_roles = optional(map(string), {})
email_addresses = optional(map(string), {})
folder_ids = optional(map(string), {})
kms_keys = optional(map(string), {})
iam_principals = optional(map(string), {})
locations = optional(map(string), {})
project_ids = optional(map(string), {})
storage_buckets = optional(map(string), {})
tag_keys = optional(map(string), {})
tag_values = optional(map(string), {})
cidr_ranges_sets = optional(map(list(string)), {})
custom_roles = optional(map(string), {})
email_addresses = optional(map(string), {})
folder_ids = optional(map(string), {})
kms_keys = optional(map(string), {})
iam_principals = optional(map(string), {})
locations = optional(map(string), {})
project_ids = optional(map(string), {})
storage_buckets = optional(map(string), {})
tag_keys = optional(map(string), {})
tag_values = optional(map(string), {})
tag_vars = optional(object({
projects = optional(map(map(string)), {})
organization = optional(map(string), {})
}), {})
vpc_sc_perimeters = optional(map(string), {})
})
default = {}

View File

@@ -487,7 +487,7 @@ Pattern-based files make specific assumptions:
| [data_defaults](variables-projects.tf#L17) | Optional default values used when corresponding project or folder data from files are missing. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [data_merges](variables-projects.tf#L93) | Optional values that will be merged with corresponding data from files. Combines with `data_defaults`, file data, and `data_overrides`. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [data_overrides](variables-projects.tf#L112) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [factories_config](variables.tf#L37) | Path to folder with YAML resource description data files. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [factories_config](variables.tf#L41) | Path to folder with YAML resource description data files. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [folder_ids](variables-fast.tf#L42) | Folders created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [host_project_ids](variables-fast.tf#L58) | Host project for the shared VPC. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>2-networking</code> |
| [iam_principals](variables-fast.tf#L50) | IAM-format principals. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
@@ -495,10 +495,10 @@ Pattern-based files make specific assumptions:
| [perimeters](variables-fast.tf#L84) | Optional VPC-SC perimeter ids. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-vpcsc</code> |
| [project_ids](variables-fast.tf#L102) | Projects created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [service_accounts](variables-fast.tf#L110) | Service accounts created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [stage_name](variables.tf#L58) | FAST stage name. Used to separate output files across different factories. | <code>string</code> | | <code>&#34;2-project-factory&#34;</code> | |
| [stage_name](variables.tf#L62) | FAST stage name. Used to separate output files across different factories. | <code>string</code> | | <code>&#34;2-project-factory&#34;</code> | |
| [subnet_self_links](variables-fast.tf#L118) | Shared VPC subnet IDs. | <code>map&#40;map&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> | <code>2-networking</code> |
| [tag_keys](variables-fast.tf#L134) | FAST-managed resource manager tag keys. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [tag_values](variables-fast.tf#L126) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [tag_vars](variables-fast.tf#L134) | FAST-managed resource manager tag key namespaced names. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [universe](variables-fast.tf#L145) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-globals</code> |
## Outputs

View File

@@ -18,7 +18,8 @@
locals {
_context = {
for k, v in var.context : k => merge(v, try(local.defaults.context[k], {}))
for k, v in var.context :
k => merge(v, try(local.defaults.context[k], {}))
}
context = merge(local._context, {
vpc_sc_perimeters = merge(var.perimeters, local._context.vpc_sc_perimeters)
@@ -104,11 +105,12 @@ module "factory" {
)
tag_values = merge(var.tag_values, local.context.tag_values)
tag_vars = {
projects = try(local.context.tag_vars.projects, {})
organization = merge({
for k, v in var.tag_keys : k => v.namespaced_name
if v.allowed_values_regex != null
}, try(local.context.tag_vars.organization, {}))
organization = merge(
var.tag_vars.organization, local.context.tag_vars.organization
)
projects = merge(
var.tag_vars.projects, local.context.tag_vars.projects
)
}
vpc_sc_perimeters = merge(var.perimeters, local.context.vpc_sc_perimeters)
}

View File

@@ -131,15 +131,15 @@ variable "tag_values" {
default = {}
}
variable "tag_keys" {
variable "tag_vars" {
# tfdoc:variable:source 0-org-setup
description = "FAST-managed resource manager tag keys."
type = map(object({
namespaced_name = string
allowed_values_regex = optional(string)
}))
default = {}
description = "FAST-managed resource manager tag key namespaced names."
type = object({
projects = optional(map(map(string)), {})
organization = optional(map(string), {})
})
nullable = false
default = {}
}
variable "universe" {

View File

@@ -27,8 +27,12 @@ variable "context" {
notification_channels = optional(map(string), {})
project_ids = optional(map(string), {})
tag_values = optional(map(string), {})
vpc_host_projects = optional(map(string), {})
vpc_sc_perimeters = optional(map(string), {})
tag_vars = optional(object({
projects = optional(map(map(string)), {})
organization = optional(map(string), {})
}), {})
vpc_host_projects = optional(map(string), {})
vpc_sc_perimeters = optional(map(string), {})
})
default = {}
nullable = false

View File

@@ -191,16 +191,17 @@ A reference Certificate Authority Services (CAS) is also part of this stage, all
| [prefix](variables-fast.tf#L57) | Prefix used for resources that need unique names. Use a maximum of 9 chars for organizations, and 11 chars for tenants. | <code>string</code> | ✓ | | <code>0-org-setup</code> |
| [context](variables.tf#L17) | Context-specific interpolations. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [custom_roles](variables-fast.tf#L25) | Custom roles defined at the org level, in key => id format. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [factories_config](variables.tf#L36) | Configuration for the resource factories or external data. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [factories_config](variables.tf#L40) | Configuration for the resource factories or external data. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | |
| [folder_ids](variables-fast.tf#L33) | Folders created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [iam_principals](variables-fast.tf#L41) | IAM-format principals. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [perimeters](variables-fast.tf#L49) | Optional VPC-SC perimeter ids. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>1-vpcsc</code> |
| [project_ids](variables-fast.tf#L67) | Projects created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [service_accounts](variables-fast.tf#L75) | Service accounts created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [storage_buckets](variables-fast.tf#L83) | Storage buckets created in the bootstrap stage. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [tag_keys](variables-fast.tf#L91) | FAST-managed resource manager tag keys. | <code>map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [tag_values](variables-fast.tf#L102) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [universe](variables-fast.tf#L110) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-org-setup</code> |
| [tag_keys](variables-fast.tf#L91) | FAST-managed resource manager tag keys. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [tag_values](variables-fast.tf#L99) | FAST-managed resource manager tag values. | <code>map&#40;string&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [tag_vars](variables-fast.tf#L107) | FAST-managed resource manager tag key namespaced names. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>&#123;&#125;</code> | <code>0-org-setup</code> |
| [universe](variables-fast.tf#L118) | GCP universe where to deploy projects. The prefix will be prepended to the project id. | <code>object&#40;&#123;&#8230;&#125;&#41;</code> | | <code>null</code> | <code>0-org-setup</code> |
## Outputs

View File

@@ -43,11 +43,12 @@ locals {
tag_keys = merge(var.tag_keys, local._ctx.tag_keys)
tag_values = merge(var.tag_values, local._ctx.tag_values)
tag_vars = {
projects = try(local._ctx.tag_vars.projects, {})
organization = merge({
for k, v in var.tag_keys : k => v.namespaced_name
if v.allowed_values_regex != null
}, try(local._ctx.tag_vars.organization, {}))
organization = merge(
var.tag_vars.organization, local._ctx.tag_vars.organization
)
projects = merge(
var.tag_vars.projects, local._ctx.tag_vars.projects
)
}
vpc_sc_perimeters = merge(var.perimeters, local._ctx.vpc_sc_perimeters)
})

View File

@@ -91,12 +91,9 @@ variable "storage_buckets" {
variable "tag_keys" {
# tfdoc:variable:source 0-org-setup
description = "FAST-managed resource manager tag keys."
type = map(object({
namespaced_name = string
allowed_values_regex = optional(string)
}))
default = {}
nullable = false
type = map(string)
nullable = false
default = {}
}
variable "tag_values" {
@@ -107,6 +104,17 @@ variable "tag_values" {
default = {}
}
variable "tag_vars" {
# tfdoc:variable:source 0-org-setup
description = "FAST-managed resource manager tag key namespaced names."
type = object({
projects = optional(map(map(string)), {})
organization = optional(map(string), {})
})
nullable = false
default = {}
}
variable "universe" {
# tfdoc:variable:source 0-org-setup
description = "GCP universe where to deploy projects. The prefix will be prepended to the project id."

View File

@@ -17,16 +17,20 @@
variable "context" {
description = "Context-specific interpolations."
type = object({
condition_vars = optional(map(map(string)), {})
email_addresses = optional(map(string), {})
custom_roles = optional(map(string), {})
folder_ids = optional(map(string), {})
iam_principals = optional(map(string), {})
locations = optional(map(string), {})
project_ids = optional(map(string), {})
storage_buckets = optional(map(string), {})
tag_keys = optional(map(string), {})
tag_values = optional(map(string), {})
condition_vars = optional(map(map(string)), {})
email_addresses = optional(map(string), {})
custom_roles = optional(map(string), {})
folder_ids = optional(map(string), {})
iam_principals = optional(map(string), {})
locations = optional(map(string), {})
project_ids = optional(map(string), {})
storage_buckets = optional(map(string), {})
tag_keys = optional(map(string), {})
tag_values = optional(map(string), {})
tag_vars = optional(object({
projects = optional(map(map(string)), {})
organization = optional(map(string), {})
}), {})
vpc_sc_perimeters = optional(map(string), {})
})
default = {}

View File

@@ -894,20 +894,20 @@ compute.disableSerialPortAccess:
| name | description | sensitive |
|---|---|:---:|
| [folder_ids](outputs.tf#L91) | Folder ids. | |
| [iam_principals](outputs.tf#L96) | IAM principals mappings. | |
| [kms_keys](outputs.tf#L101) | KMS key ids. | |
| [log_buckets](outputs.tf#L106) | Log bucket ids. | |
| [project_ids](outputs.tf#L113) | Project ids. | |
| [project_numbers](outputs.tf#L118) | Project numbers. | |
| [projects](outputs.tf#L125) | Project attributes. | |
| [pubsub_topics](outputs.tf#L130) | PubSub topic ids. | |
| [service_account_emails](outputs.tf#L137) | Service account emails. | |
| [service_account_iam_emails](outputs.tf#L144) | Service account IAM-format emails. | |
| [service_account_ids](outputs.tf#L151) | Service account IDs. | |
| [service_accounts](outputs.tf#L158) | Service account emails. | |
| [service_agents](outputs.tf#L163) | Service agent emails. | |
| [storage_buckets](outputs.tf#L174) | Bucket names. | |
| [folder_ids](outputs.tf#L102) | Folder ids. | |
| [iam_principals](outputs.tf#L107) | IAM principals mappings. | |
| [kms_keys](outputs.tf#L112) | KMS key ids. | |
| [log_buckets](outputs.tf#L117) | Log bucket ids. | |
| [project_ids](outputs.tf#L124) | Project ids. | |
| [project_numbers](outputs.tf#L129) | Project numbers. | |
| [projects](outputs.tf#L136) | Project attributes. | |
| [pubsub_topics](outputs.tf#L141) | PubSub topic ids. | |
| [service_account_emails](outputs.tf#L148) | Service account emails. | |
| [service_account_iam_emails](outputs.tf#L155) | Service account IAM-format emails. | |
| [service_account_ids](outputs.tf#L162) | Service account IDs. | |
| [service_accounts](outputs.tf#L169) | Service account emails. | |
| [service_agents](outputs.tf#L174) | Service agent emails. | |
| [storage_buckets](outputs.tf#L185) | Bucket names. | |
<!-- END TFDOC -->
## Tests

View File

@@ -66,6 +66,17 @@ locals {
module.buckets["${k}/${sk}"].name
)
}
tag_keys = {
for sk, sv in module.projects[k].tag_keys : sk => sv.id
}
tag_values = {
for sk, sv in module.projects[k].tag_values : sk => sv.id
}
tag_vars = {
for sk, sv in module.projects[k].tag_keys : sk => sv.namespaced_name
# the provider returns allowed_values_regex set to "" not null
if try(sv.allowed_values_regex, "") != ""
}
workload_identity_pools = (
module.projects[k].workload_identity_pool_ids
)