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({