From 7a5664f475e692333e3ca07a987fd7456475d402 Mon Sep 17 00:00:00 2001 From: Ludovico Magnocavallo Date: Thu, 5 Mar 2026 10:32:35 +0100 Subject: [PATCH] Additional changes to folder module and project factory (#3782) * allow null name, use basepath for factories in pf folders * fix id in folder schema --- .../0-org-setup/schemas/folder.schema.json | 2 +- .../2-networking/schemas/folder.schema.json | 2 +- .../schemas/folder.schema.json | 2 +- .../2-security/schemas/folder.schema.json | 2 +- modules/project-factory/README.md | 2 +- modules/project-factory/folders.tf | 76 ++++++++++++++----- .../schemas/folder.schema.json | 2 +- tools/duplicate-diff.py | 8 +- 8 files changed, 65 insertions(+), 31 deletions(-) diff --git a/fast/stages/0-org-setup/schemas/folder.schema.json b/fast/stages/0-org-setup/schemas/folder.schema.json index 3150efbcd..bc98f32d0 100644 --- a/fast/stages/0-org-setup/schemas/folder.schema.json +++ b/fast/stages/0-org-setup/schemas/folder.schema.json @@ -262,7 +262,7 @@ }, "id": { "type": "string", - "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$" + "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_/-]+)$" }, "firewall_policy": { "type": "object", diff --git a/fast/stages/2-networking/schemas/folder.schema.json b/fast/stages/2-networking/schemas/folder.schema.json index 3150efbcd..bc98f32d0 100644 --- a/fast/stages/2-networking/schemas/folder.schema.json +++ b/fast/stages/2-networking/schemas/folder.schema.json @@ -262,7 +262,7 @@ }, "id": { "type": "string", - "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$" + "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_/-]+)$" }, "firewall_policy": { "type": "object", diff --git a/fast/stages/2-project-factory/schemas/folder.schema.json b/fast/stages/2-project-factory/schemas/folder.schema.json index 3150efbcd..bc98f32d0 100644 --- a/fast/stages/2-project-factory/schemas/folder.schema.json +++ b/fast/stages/2-project-factory/schemas/folder.schema.json @@ -262,7 +262,7 @@ }, "id": { "type": "string", - "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$" + "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_/-]+)$" }, "firewall_policy": { "type": "object", diff --git a/fast/stages/2-security/schemas/folder.schema.json b/fast/stages/2-security/schemas/folder.schema.json index 3150efbcd..bc98f32d0 100644 --- a/fast/stages/2-security/schemas/folder.schema.json +++ b/fast/stages/2-security/schemas/folder.schema.json @@ -262,7 +262,7 @@ }, "id": { "type": "string", - "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$" + "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_/-]+)$" }, "firewall_policy": { "type": "object", diff --git a/modules/project-factory/README.md b/modules/project-factory/README.md index 10b5bbcf9..a5a9526d5 100644 --- a/modules/project-factory/README.md +++ b/modules/project-factory/README.md @@ -557,7 +557,7 @@ asset_feeds: ```yaml name: App 0 factories_config: - org_policies: data/factories/org-policies + org_policies: ./data/factories/org-policies pam_entitlements: app-0-admins: max_request_duration: 3600s diff --git a/modules/project-factory/folders.tf b/modules/project-factory/folders.tf index 8338d7c7c..4d0ff561e 100644 --- a/modules/project-factory/folders.tf +++ b/modules/project-factory/folders.tf @@ -58,10 +58,14 @@ module "folder-1" { id = lookup(each.value, "id", null) deletion_protection = lookup(each.value, "deletion_protection", false) parent = coalesce(each.value.parent, "$folder_ids:default") - name = each.value.name + name = try(each.value.name, null) factories_config = { - org_policies = try(each.value.factories_config.org_policies, null) - scc_sha_custom_modules = try(each.value.factories_config.scc_sha_custom_modules, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["org_policies", "scc_sha_custom_modules"], k) } org_policies = lookup(each.value, "org_policies", {}) pam_entitlements = lookup(each.value, "pam_entitlements", {}) @@ -80,9 +84,14 @@ module "folder-1-iam" { id = module.folder-1[each.key].id asset_feeds = lookup(each.value, "asset_feeds", {}) asset_search = lookup(each.value, "asset_search", {}) + # we do anything that can refer to IAM and custom roles in this call factories_config = { - # we do anything that can refer to IAM and custom roles in this call - pam_entitlements = try(each.value.factories_config.pam_entitlements, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["pam_entitlements"], k) } autokey_config = lookup(each.value, "autokey_config", null) iam = lookup(each.value, "iam", {}) @@ -112,10 +121,14 @@ module "folder-2" { parent = coalesce( each.value.parent, "$folder_ids:${each.value.parent_key}" ) - name = each.value.name + name = try(each.value.name, null) factories_config = { - org_policies = try(each.value.factories_config.org_policies, null) - scc_sha_custom_modules = try(each.value.factories_config.scc_sha_custom_modules, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["org_policies", "scc_sha_custom_modules"], k) } org_policies = lookup(each.value, "org_policies", {}) pam_entitlements = lookup(each.value, "pam_entitlements", {}) @@ -139,9 +152,14 @@ module "folder-2-iam" { id = module.folder-2[each.key].id asset_feeds = lookup(each.value, "asset_feeds", {}) asset_search = lookup(each.value, "asset_search", {}) + # we do anything that can refer to IAM and custom roles in this call factories_config = { - # we do anything that can refer to IAM and custom roles in this call - pam_entitlements = try(each.value.factories_config.pam_entitlements, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["pam_entitlements"], k) } autokey_config = lookup(each.value, "autokey_config", null) iam = lookup(each.value, "iam", {}) @@ -174,10 +192,14 @@ module "folder-3" { parent = coalesce( each.value.parent, "$folder_ids:${each.value.parent_key}" ) - name = each.value.name + name = try(each.value.name, null) factories_config = { - org_policies = try(each.value.factories_config.org_policies, null) - scc_sha_custom_modules = try(each.value.factories_config.scc_sha_custom_modules, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["org_policies", "scc_sha_custom_modules"], k) } org_policies = lookup(each.value, "org_policies", {}) pam_entitlements = lookup(each.value, "pam_entitlements", {}) @@ -201,9 +223,14 @@ module "folder-3-iam" { id = module.folder-3[each.key].id asset_feeds = lookup(each.value, "asset_feeds", {}) asset_search = lookup(each.value, "asset_search", {}) + # we do anything that can refer to IAM and custom roles in this call factories_config = { - # we do anything that can refer to IAM and custom roles in this call - pam_entitlements = try(each.value.factories_config.pam_entitlements, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["pam_entitlements"], k) } autokey_config = lookup(each.value, "autokey_config", null) iam = lookup(each.value, "iam", {}) @@ -236,10 +263,14 @@ module "folder-4" { parent = coalesce( each.value.parent, "$folder_ids:${each.value.parent_key}" ) - name = each.value.name + name = try(each.value.name, null) factories_config = { - org_policies = try(each.value.factories_config.org_policies, null) - scc_sha_custom_modules = try(each.value.factories_config.scc_sha_custom_modules, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["org_policies", "scc_sha_custom_modules"], k) } org_policies = lookup(each.value, "org_policies", {}) pam_entitlements = lookup(each.value, "pam_entitlements", {}) @@ -263,9 +294,14 @@ module "folder-4-iam" { id = module.folder-4[each.key].id asset_feeds = lookup(each.value, "asset_feeds", {}) asset_search = lookup(each.value, "asset_search", {}) + # we do anything that can refer to IAM and custom roles in this call factories_config = { - # we do anything that can refer to IAM and custom roles in this call - pam_entitlements = try(each.value.factories_config.pam_entitlements, null) + for k, v in lookup(each.value, "factories_config", {}) : k => try(pathexpand( + var.factories_config.basepath == null || startswith(v, "/") || startswith(v, ".") + ? v : + "${var.factories_config.basepath}/${v}" + ), null) + if contains(["pam_entitlements"], k) } autokey_config = lookup(each.value, "autokey_config", null) iam = lookup(each.value, "iam", {}) diff --git a/modules/project-factory/schemas/folder.schema.json b/modules/project-factory/schemas/folder.schema.json index 3150efbcd..bc98f32d0 100644 --- a/modules/project-factory/schemas/folder.schema.json +++ b/modules/project-factory/schemas/folder.schema.json @@ -262,7 +262,7 @@ }, "id": { "type": "string", - "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_-]+)$" + "pattern": "^(folders/[0-9]+|\\$folder_ids:[a-z0-9_/-]+)$" }, "firewall_policy": { "type": "object", diff --git a/tools/duplicate-diff.py b/tools/duplicate-diff.py index d014d9f21..c619718e3 100755 --- a/tools/duplicate-diff.py +++ b/tools/duplicate-diff.py @@ -54,11 +54,11 @@ duplicates = [ "modules/net-vpc-firewall/schemas/firewall-rules.schema.json", ], [ + "modules/project-factory/schemas/folder.schema.json", "fast/stages/0-org-setup/schemas/folder.schema.json", "fast/stages/2-networking/schemas/folder.schema.json", "fast/stages/2-project-factory/schemas/folder.schema.json", "fast/stages/2-security/schemas/folder.schema.json", - "modules/project-factory/schemas/folder.schema.json", ], [ "fast/stages/0-org-setup/schemas/observability.schema.json", @@ -181,13 +181,11 @@ for group in duplicates: if is_dir: dcmp = filecmp.dircmp(first, second) if check_dir_diff(dcmp): - print( - f"[DIFF] Found differences between directories {first} and {second}" - ) + print(f"[DIFF] Found differences between directories {first} {second}") has_diff = True else: if not filecmp.cmp(first, second, shallow=False): - print(f"[DIFF] Files are different: {first} and {second}") + print(f"[DIFF] Files are different: {first} {second}") has_diff = True if has_diff: