diff --git a/modules/project-factory/README.md b/modules/project-factory/README.md
index d3f6de13b..38fc12848 100644
--- a/modules/project-factory/README.md
+++ b/modules/project-factory/README.md
@@ -484,10 +484,10 @@ service_accounts:
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [factories_config](variables.tf#L120) | 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({…}) | | {} |
+| [data_overrides](variables.tf#L83) | Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`. | object({…}) | | {} |
## Outputs
diff --git a/modules/project-factory/factory-projects-object.tf b/modules/project-factory/factory-projects-object.tf
index 582e8256c..b9cc8c60a 100644
--- a/modules/project-factory/factory-projects-object.tf
+++ b/modules/project-factory/factory-projects-object.tf
@@ -78,9 +78,10 @@ locals {
},
try(local._projects_config.data_defaults, {})
)
+ # data_overrides default to null's, to mark that they should not override
data_overrides = merge({
billing_account = null
- contacts = {}
+ contacts = null
factories_config = merge({
custom_roles = null
observability = null
@@ -95,27 +96,25 @@ locals {
)
parent = null
prefix = null
- service_encryption_key_ids = {}
+ service_encryption_key_ids = null
storage_location = null
- tag_bindings = {}
- services = []
- service_accounts = {}
- vpc_sc = merge({
- perimeter_name = null
- perimeter_bridges = []
- is_dry_run = false
- }, try(local._projects_config.data_overrides.vpc_sc, {
- perimeter_name = null
- perimeter_bridges = []
- is_dry_run = false
- })
- )
- logging_data_access = {}
+ tag_bindings = null
+ services = null
+ service_accounts = null
+ vpc_sc = try(local._projects_config.data_overrides.vpc_sc, null)
+ logging_data_access = null
},
try(local._projects_config.data_overrides, {})
)
}
_projects_output = {
+ # Semantics of the merges are:
+ # * if data_overrides. is not null, use this value
+ # * if _projects_inputs. is not null, use this value
+ # * use data_default value, which if not set, will provide "empty" type
+ # This logic is easily implemented using coalesce, even on maps and list and allows to
+ # set data_overrides. to "", [] or {} to ensure, that empty value is always passed, or do
+ # the same in _projects_input to prevent falling back to default value
for k, v in local._projects_input : k => merge(v, {
billing_account = try(coalesce( # type: string
local.__projects_config.data_overrides.billing_account,
diff --git a/modules/project-factory/variables.tf b/modules/project-factory/variables.tf
index b5bb14812..4f9bb18db 100644
--- a/modules/project-factory/variables.tf
+++ b/modules/project-factory/variables.tf
@@ -83,6 +83,7 @@ variable "data_merges" {
variable "data_overrides" {
description = "Optional values that override corresponding data from files. Takes precedence over file data and `data_defaults`."
type = object({
+ # data overrides default to null to mark that they should not override
billing_account = optional(string)
contacts = optional(map(list(string)))
factories_config = optional(object({
@@ -111,7 +112,7 @@ variable "data_overrides" {
ADMIN_READ = optional(object({ exempted_members = optional(list(string)) })),
DATA_READ = optional(object({ exempted_members = optional(list(string)) })),
DATA_WRITE = optional(object({ exempted_members = optional(list(string)) }))
- })), {})
+ })))
})
nullable = false
default = {}