diff --git a/modules/project-factory/README.md b/modules/project-factory/README.md
index f95815588..4180e7e22 100644
--- a/modules/project-factory/README.md
+++ b/modules/project-factory/README.md
@@ -898,11 +898,11 @@ compute.disableSerialPortAccess:
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [factories_config](variables.tf#L170) | Path to folder with YAML resource description data files. Exclusions match the start of file paths, relative to their containing folder. | object({…}) | ✓ | |
+| [factories_config](variables.tf#L194) | Path to folder with YAML resource description data files. Exclusions match the start of file paths, relative to their containing folder. | object({…}) | ✓ | |
| [context](variables.tf#L17) | Context-specific interpolations. | object({…}) | | {} |
| [data_defaults](variables.tf#L47) | Optional default values used when corresponding project or folder data from files are missing. | object({…}) | | {} |
-| [data_merges](variables.tf#L112) | 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#L131) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | object({…}) | | {} |
+| [data_merges](variables.tf#L124) | 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#L143) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | object({…}) | | {} |
| [folders](variables-folders.tf#L17) | Folders data merged with factory data. | map(object({…})) | | {} |
| [notification_channels](variables-billing.tf#L17) | Notification channels used by budget alerts. | map(object({…})) | | {} |
| [projects](variables-projects.tf#L17) | Projects data merged with factory data. | map(object({…})) | | {} |
diff --git a/modules/project-factory/projects-defaults.tf b/modules/project-factory/projects-defaults.tf
index 4a7f5e6a1..9cc672f41 100644
--- a/modules/project-factory/projects-defaults.tf
+++ b/modules/project-factory/projects-defaults.tf
@@ -51,16 +51,56 @@ locals {
local.data_defaults.defaults.contacts
)
factories_config = {
- aspect_types = try(v.factories_config.aspect_types, null)
- custom_roles = try(v.factories_config.custom_roles, null)
- data_catalog_taxonomy = try(v.factories_config.data_catalog_taxonomy, 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)
+ aspect_types = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.aspect_types, null),
+ try(v.factories_config.aspect_types, null),
+ try(local.data_defaults.defaults.factories_config.aspect_types, null),
+ ), null)
+ custom_roles = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.custom_roles, null),
+ try(v.factories_config.custom_roles, null),
+ try(local.data_defaults.defaults.factories_config.custom_roles, null),
+ ), null)
+ data_catalog_taxonomy = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.data_catalog_taxonomy, null),
+ try(v.factories_config.data_catalog_taxonomy, null),
+ try(local.data_defaults.defaults.factories_config.data_catalog_taxonomy, null),
+ ), null)
+ observability = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.observability, null),
+ try(v.factories_config.observability, null),
+ try(local.data_defaults.defaults.factories_config.observability, null),
+ ), null)
+ org_policies = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.org_policies, null),
+ try(v.factories_config.org_policies, null),
+ try(local.data_defaults.defaults.factories_config.org_policies, null),
+ ), null)
+ pam_entitlements = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.pam_entitlements, null),
+ try(v.factories_config.pam_entitlements, null),
+ try(local.data_defaults.defaults.factories_config.pam_entitlements, null),
+ ), null)
+ quotas = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.quotas, null),
+ try(v.factories_config.quotas, null),
+ try(local.data_defaults.defaults.factories_config.quotas, null),
+ ), null)
+ scc_mute_configs = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.scc_mute_configs, null),
+ try(v.factories_config.scc_mute_configs, null),
+ try(local.data_defaults.defaults.factories_config.scc_mute_configs, null),
+ ), null)
+ scc_sha_custom_modules = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.scc_sha_custom_modules, null),
+ try(v.factories_config.scc_sha_custom_modules, null),
+ try(local.data_defaults.defaults.factories_config.scc_sha_custom_modules, null),
+ ), null)
+ tags = try(coalesce(
+ try(local.data_defaults.overrides.factories_config.tags, null),
+ try(v.factories_config.tags, null),
+ try(local.data_defaults.defaults.factories_config.tags, null),
+ ), null)
}
iam = try(v.iam, {}) # type: map(list(string))
iam_bindings = try(v.iam_bindings, {}) # type: map(object({...}))
diff --git a/modules/project-factory/projects.tf b/modules/project-factory/projects.tf
index 8ad850134..7106d00e3 100644
--- a/modules/project-factory/projects.tf
+++ b/modules/project-factory/projects.tf
@@ -212,6 +212,10 @@ module "projects-iam" {
lookup(local.self_sas_iam_emails, each.key, {}),
local.projects_service_agents
)
+ custom_roles = merge(
+ try(local.ctx.custom_roles, {}),
+ module.projects[each.key].custom_role_id
+ )
project_ids = merge(
local.ctx.project_ids,
{ for k, v in module.projects : k => v.project_id }
diff --git a/modules/project-factory/variables.tf b/modules/project-factory/variables.tf
index 2a15d8100..291134dfe 100644
--- a/modules/project-factory/variables.tf
+++ b/modules/project-factory/variables.tf
@@ -53,7 +53,19 @@ variable "data_defaults" {
}), {})
contacts = optional(map(list(string)), {})
deletion_policy = optional(string)
- labels = optional(map(string), {})
+ factories_config = optional(object({
+ aspect_types = optional(string)
+ custom_roles = optional(string)
+ data_catalog_taxonomy = 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)
+ }), {})
+ labels = optional(map(string), {})
locations = optional(object({
bigquery = optional(string)
logging = optional(string)
@@ -138,6 +150,18 @@ variable "data_overrides" {
}), {})
contacts = optional(map(list(string)))
deletion_policy = optional(string)
+ factories_config = optional(object({
+ aspect_types = optional(string)
+ custom_roles = optional(string)
+ data_catalog_taxonomy = 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)
+ }))
locations = optional(object({
bigquery = optional(string)
logging = optional(string)