Change factories_config type in FAST and project/vpc factory modules, add YAML schema validation (#3728)

* stage 0

* stage 1

* networking

* security

* pf stage

* tfdoc

* align schemas

* inventory

* fix observability

* pf module

* pf module budgets

* align fast stages

* align project subfactories

* tfdoc

* schema validation

* add missing schemas

* Fix observability types

---------

Co-authored-by: Julio Castillo <jccb@google.com>
This commit is contained in:
Ludovico Magnocavallo
2026-02-11 16:29:49 +01:00
committed by GitHub
parent bf3f7a555a
commit fb21f6aaf8
125 changed files with 1024 additions and 432 deletions

File diff suppressed because one or more lines are too long

View File

@@ -17,6 +17,10 @@
# tfdoc:file:description Billing budget factory locals.
locals {
budgets_enabled = (
var.factories_config.budgets.billing_account != null &&
local.paths.budgets != null
)
budget_folder_sets = flatten([
for k, v in local.folders_input : [
for vv in try(v.billing_budgets, []) : {
@@ -37,8 +41,8 @@ locals {
module "billing-budgets" {
source = "../billing-account"
count = var.factories_config.budgets != null ? 1 : 0
id = var.factories_config.budgets.billing_account_id
count = local.budgets_enabled ? 1 : 0
id = var.factories_config.budgets.billing_account
context = merge(local.ctx, {
folder_ids = local.ctx.folder_ids
folder_sets = {
@@ -53,7 +57,7 @@ module "billing-budgets" {
project_numbers = local.ctx_project_numbers
})
factories_config = {
budgets_data_path = var.factories_config.budgets.data
budgets_data_path = local.paths.budgets
}
budget_notification_channels = (
var.notification_channels

View File

@@ -19,18 +19,15 @@
# TODO: folder automation
locals {
_folders_path = try(
pathexpand(var.factories_config.folders), null
)
_folders_files = try(
fileset(local._folders_path, "**/**/.config.yaml"),
fileset(local.paths.folders, "**/**/.config.yaml"),
[]
)
_folders_raw = merge(
var.folders,
{
for f in local._folders_files : dirname(f) => yamldecode(file(
"${coalesce(local._folders_path, "-")}/${f}"
"${coalesce(local.paths.folders, "-")}/${f}"
))
}
)

View File

@@ -26,6 +26,13 @@ locals {
local.projects_sas_iam_emails,
local.automation_sas_iam_emails
)
paths = {
for k, v in var.factories_config.paths : k => try(pathexpand(
var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".")
? v :
"${var.factories_config.basepath}/${v}"
), null)
}
}
resource "terraform_data" "defaults_preconditions" {
@@ -38,8 +45,8 @@ resource "terraform_data" "defaults_preconditions" {
error_message = "No default storage location defined in defaults or overrides variables."
}
# precondition {
# condition = local.projects_input == null
# error_message = jsonencode(local.ctx_tag_values)
# condition = local.paths == null
# error_message = jsonencode(local.paths)
# }
}
}

View File

@@ -50,7 +50,16 @@ locals {
try(v.contacts, null),
local.data_defaults.defaults.contacts
)
factories_config = try(v.factories_config, {})
factories_config = {
custom_roles = try(v.factories_config.custom_roles, null)
observability = try(v.factories_config.observability, null)
org_policies = try(v.factories_config.org_policies, null)
pam_entitlements = try(v.factories_config.pam_entitlements, null)
quotas = try(v.factories_config.quotas, null)
scc_mute_configs = try(v.factories_config.scc_mute_configs, null)
scc_sha_custom_modules = try(v.factories_config.scc_sha_custom_modules, null)
tags = try(v.factories_config.tags, null)
}
iam = try(v.iam, {}) # type: map(list(string))
iam_bindings = try(v.iam_bindings, {}) # type: map(object({...}))
iam_bindings_additive = try(v.iam_bindings_additive, {}) # type: map(object({...}))

View File

@@ -19,10 +19,10 @@
locals {
# project data from folders tree
_folder_projects_raw = {
for f in try(fileset(local._folders_path, "**/*.yaml"), []) :
for f in try(fileset(local.paths.folders, "**/*.yaml"), []) :
trimsuffix(f, ".yaml") => merge(
{ parent = dirname(f) == "." ? null : "$folder_ids:${dirname(f)}" },
yamldecode(file("${local._folders_path}/${f}"))
yamldecode(file("${local.paths.folders}/${f}"))
) if !endswith(f, "/.config.yaml")
}
_projects_input = {
@@ -32,16 +32,13 @@ locals {
v
)
}
_projects_path = try(
pathexpand(var.factories_config.projects), null
)
_projects_raw = {
for f in try(fileset(local._projects_path, "**/*.yaml"), []) :
trimsuffix(f, ".yaml") => yamldecode(file("${local._projects_path}/${f}"))
for f in try(fileset(local.paths.projects, "**/*.yaml"), []) :
trimsuffix(f, ".yaml") => yamldecode(file("${local.paths.projects}/${f}"))
if !endswith(f, ".config.yaml")
}
_templates_path = try(
pathexpand(var.factories_config.project_templates), null
pathexpand(local.paths.project_templates), null
)
_templates_raw = {
for f in try(fileset(local._templates_path, "**/*.yaml"), []) :
@@ -121,12 +118,11 @@ module "projects" {
})
default_service_account = try(each.value.default_service_account, "keep")
factories_config = {
custom_roles = try(each.value.factories_config.custom_roles, null)
org_policies = try(each.value.factories_config.org_policies, null)
observability = try(each.value.factories_config.observability, null)
quotas = try(each.value.factories_config.quotas, null)
scc_sha_custom_modules = try(each.value.factories_config.scc_sha_custom_modules, null)
tags = try(each.value.factories_config.tags, null)
for k, v in each.value.factories_config : k => try(pathexpand(
var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".")
? v :
"${var.factories_config.basepath}/${v}"
), null)
}
kms_autokeys = try(each.value.kms.autokeys, {})
labels = merge(

View File

@@ -425,7 +425,7 @@
"type": "object",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9-]+$": {
"^[a-zA-Z0-9_-]+$": {
"$ref": "#/$defs/log_bucket"
}
}

View File

@@ -231,6 +231,16 @@ variable "projects" {
friendly_name = optional(string)
location = optional(string)
})), {})
factories_config = optional(object({
custom_roles = optional(string)
observability = optional(string)
org_policies = optional(string)
pam_entitlements = optional(string)
quotas = optional(string)
scc_mute_configs = optional(string)
scc_sha_custom_modules = optional(string)
tags = optional(string)
}), {})
iam = optional(map(list(string)), {})
iam_bindings = optional(map(object({
members = list(string)

View File

@@ -165,13 +165,16 @@ variable "data_overrides" {
variable "factories_config" {
description = "Path to folder with YAML resource description data files."
type = object({
folders = optional(string)
project_templates = optional(string)
projects = optional(string)
basepath = string
budgets = optional(object({
billing_account_id = string
data = string
}))
billing_account = optional(string)
}), {})
paths = optional(object({
budgets = optional(string, "budgets")
folders = optional(string, "folders")
project_templates = optional(string, "project-templates")
projects = optional(string, "projects")
}), {})
})
nullable = false
}