diff --git a/modules/net-vpc-factory/README.md b/modules/net-vpc-factory/README.md index aa40b3fd8..a5a1ccf22 100644 --- a/modules/net-vpc-factory/README.md +++ b/modules/net-vpc-factory/README.md @@ -816,6 +816,7 @@ vpc_config: | [prefix](variables.tf#L379) | Prefix used for projects. | string | ✓ | | | [factories_config](variables.tf#L22) | Configuration for network resource factories. | object({…}) | | {…} | | [network_project_config](variables.tf#L33) | Consolidated configuration for project, VPCs and their associated resources. | map(object({…})) | | null | +| [project_reuse](variables.tf#L384) | Reuse existing project if not null. If name and number are not passed in, a data source is used. | object({…}) | | null | ## Outputs diff --git a/modules/net-vpc-factory/factory-project.tf b/modules/net-vpc-factory/factory-project.tf index 4e7ae1992..f28949aa5 100644 --- a/modules/net-vpc-factory/factory-project.tf +++ b/modules/net-vpc-factory/factory-project.tf @@ -23,6 +23,7 @@ locals { billing_account = var.billing_account prefix = var.prefix parent = var.parent_id + project_reuse = var.project_reuse } } projects = local._projects_output @@ -43,4 +44,5 @@ module "projects" { iam_by_principals = each.value.iam_by_principals iam_by_principals_additive = each.value.iam_by_principals_additive org_policies = each.value.org_policies + project_reuse = each.value.project_reuse } diff --git a/modules/net-vpc-factory/factory-projects-object.tf b/modules/net-vpc-factory/factory-projects-object.tf index cbc9685ea..1e7a8c3f5 100644 --- a/modules/net-vpc-factory/factory-projects-object.tf +++ b/modules/net-vpc-factory/factory-projects-object.tf @@ -39,10 +39,18 @@ locals { quotas = null }) ) - labels = {} - metric_scopes = [] - parent = null - prefix = null + labels = {} + metric_scopes = [] + parent = null + prefix = null + project_reuse = merge({ + use_data_source = true + project_attributes = null + }, try(local._projects_config.data_defaults.project_reuse, { + use_data_source = true + project_attributes = null + }) + ) service_encryption_key_ids = {} services = [] shared_vpc_service_config = merge({ @@ -196,6 +204,17 @@ locals { local.__projects_config.data_defaults.prefix ), null ) + project_reuse = ( # type: object({...}) + try(v.project_reuse, null) != null + ? merge( + { + use_data_source = true + project_attributes = null + }, + v.project_reuse + ) + : local.__projects_config.data_defaults.project_reuse + ) service_encryption_key_ids = coalesce( # type: map(list(string)) local.__projects_config.data_overrides.service_encryption_key_ids, try(v.service_encryption_key_ids, null), diff --git a/modules/net-vpc-factory/schemas/network-project.schema.json b/modules/net-vpc-factory/schemas/network-project.schema.json index 130f42868..b50b66154 100644 --- a/modules/net-vpc-factory/schemas/network-project.schema.json +++ b/modules/net-vpc-factory/schemas/network-project.schema.json @@ -35,6 +35,36 @@ "parent": { "type": "string" }, + "project_reuse": { + "type": "object", + "additionalProperties": false, + "properties": { + "use_data_source": { + "type": "boolean" + }, + "project_attributes": { + "type": "object", + "required": [ + "name", + "number" + ], + "properties": { + "name": { + "type": "string" + }, + "number": { + "type": "number" + }, + "services_enabled": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, "billing_account": { "type": "string" }, @@ -1476,4 +1506,4 @@ } } } -} \ No newline at end of file +} diff --git a/modules/net-vpc-factory/variables.tf b/modules/net-vpc-factory/variables.tf index efab6f08c..37f8f0231 100644 --- a/modules/net-vpc-factory/variables.tf +++ b/modules/net-vpc-factory/variables.tf @@ -380,3 +380,23 @@ variable "prefix" { description = "Prefix used for projects." type = string } + +variable "project_reuse" { + description = "Reuse existing project if not null. If name and number are not passed in, a data source is used." + type = object({ + use_data_source = optional(bool, true) + project_attributes = optional(object({ + name = string + number = number + services_enabled = optional(list(string), []) + })) + }) + default = null + validation { + condition = ( + try(var.project_reuse.use_data_source, null) != false || + try(var.project_reuse.project_attributes, null) != null + ) + error_message = "Reuse datasource can be disabled only if project attributes are set." + } +} diff --git a/modules/project-factory/README.md b/modules/project-factory/README.md index 8165d0697..41e704f23 100644 --- a/modules/project-factory/README.md +++ b/modules/project-factory/README.md @@ -494,10 +494,10 @@ service_accounts: | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [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({…}) | | {} | +| [factories_config](variables.tf#L129) | 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#L72) | 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#L91) | 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 cbc9685ea..1e7a8c3f5 100644 --- a/modules/project-factory/factory-projects-object.tf +++ b/modules/project-factory/factory-projects-object.tf @@ -39,10 +39,18 @@ locals { quotas = null }) ) - labels = {} - metric_scopes = [] - parent = null - prefix = null + labels = {} + metric_scopes = [] + parent = null + prefix = null + project_reuse = merge({ + use_data_source = true + project_attributes = null + }, try(local._projects_config.data_defaults.project_reuse, { + use_data_source = true + project_attributes = null + }) + ) service_encryption_key_ids = {} services = [] shared_vpc_service_config = merge({ @@ -196,6 +204,17 @@ locals { local.__projects_config.data_defaults.prefix ), null ) + project_reuse = ( # type: object({...}) + try(v.project_reuse, null) != null + ? merge( + { + use_data_source = true + project_attributes = null + }, + v.project_reuse + ) + : local.__projects_config.data_defaults.project_reuse + ) service_encryption_key_ids = coalesce( # type: map(list(string)) local.__projects_config.data_overrides.service_encryption_key_ids, try(v.service_encryption_key_ids, null), diff --git a/modules/project-factory/main.tf b/modules/project-factory/main.tf index 93372600b..47d78f033 100644 --- a/modules/project-factory/main.tf +++ b/modules/project-factory/main.tf @@ -42,6 +42,7 @@ module "projects" { local.context.folder_ids, each.value.parent, each.value.parent ) prefix = each.value.prefix + project_reuse = each.value.project_reuse alerts = try(each.value.alerts, null) auto_create_network = try(each.value.auto_create_network, false) compute_metadata = try(each.value.compute_metadata, {}) diff --git a/modules/project-factory/schemas/project.schema.json b/modules/project-factory/schemas/project.schema.json index fc00d4368..feb2c7416 100644 --- a/modules/project-factory/schemas/project.schema.json +++ b/modules/project-factory/schemas/project.schema.json @@ -189,6 +189,36 @@ "prefix": { "type": "string" }, + "project_reuse": { + "type": "object", + "additionalProperties": false, + "properties": { + "use_data_source": { + "type": "boolean" + }, + "project_attributes": { + "type": "object", + "required": [ + "name", + "number" + ], + "properties": { + "name": { + "type": "string" + }, + "number": { + "type": "number" + }, + "services_enabled": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + }, "service_accounts": { "type": "object", "additionalProperties": false, @@ -621,4 +651,4 @@ } } } -} \ No newline at end of file +} diff --git a/modules/project-factory/variables.tf b/modules/project-factory/variables.tf index cd76d2d17..2a9dd572a 100644 --- a/modules/project-factory/variables.tf +++ b/modules/project-factory/variables.tf @@ -25,10 +25,18 @@ variable "data_defaults" { org_policies = optional(string) quotas = optional(string) }), {}) - labels = optional(map(string), {}) - metric_scopes = optional(list(string), []) - parent = optional(string) - prefix = optional(string) + labels = optional(map(string), {}) + metric_scopes = optional(list(string), []) + parent = optional(string) + prefix = optional(string) + project_reuse = optional(object({ + use_data_source = optional(bool, true) + project_attributes = optional(object({ + name = string + number = number + services_enabled = optional(list(string), []) + })) + })) service_encryption_key_ids = optional(map(list(string)), {}) services = optional(list(string), []) shared_vpc_service_config = optional(object({