Add attachment groups factory to 2-networking (#3871)
* feat(fast): add attachment groups factory to 2-networking Adds support for `google_compute_interconnect_attachment_group` in the `2-networking` stage. By implementing this at the factory level alongside `vlan-attachments`, users can now declaratively aggregate VLAN attachments across multiple VPCs and natively reference them using the `$attachment_groups:<key>` context identifier in their configuration YAMLs. Includes: - Factory implementation in `factory-vlan-attachments.tf`. - New JSON schemas for `attachment-groups` and updates to `vlan-attachments` to support context linkage. - Test coverage with new inventory generations. Fixes #3791
This commit is contained in:
@@ -367,7 +367,7 @@ Internally created resources are mapped to context namespaces, and use specific
|
||||
| [factory-peering.tf](./factory-peering.tf) | VPC Peering factory. | | <code>google_compute_network_peering</code> |
|
||||
| [factory-projects.tf](./factory-projects.tf) | Projects factory. | <code>project-factory</code> | |
|
||||
| [factory-routers.tf](./factory-routers.tf) | Routers factory. | | <code>google_compute_router</code> |
|
||||
| [factory-vlan-attachments.tf](./factory-vlan-attachments.tf) | VLAN attachments factory. | <code>net-vlan-attachment</code> | |
|
||||
| [factory-vlan-attachments.tf](./factory-vlan-attachments.tf) | VLAN attachments factory. | <code>net-vlan-attachment</code> | <code>google_compute_interconnect_attachment_group</code> |
|
||||
| [factory-vpcs.tf](./factory-vpcs.tf) | VPC and firewall rules factory. | <code>net-vpc</code> · <code>net-vpc-factory</code> | |
|
||||
| [factory-vpns.tf](./factory-vpns.tf) | VPNs factory. | <code>net-vpn-ha</code> | <code>google_compute_ha_vpn_gateway</code> |
|
||||
| [main.tf](./main.tf) | Module-level locals and resources. | | |
|
||||
|
||||
@@ -66,6 +66,87 @@ locals {
|
||||
mtu = try(v.mtu, local.vpcs[v.vpc_key].mtu, local.vpc_defaults.mtu, 1500)
|
||||
})
|
||||
}
|
||||
|
||||
_attachment_groups_files = try(
|
||||
merge([
|
||||
for vpc_key, vpc in local.vpcs : {
|
||||
for f in try(fileset(
|
||||
try(
|
||||
startswith(vpc.factories_config.attachment_groups, "/") || startswith(vpc.factories_config.attachment_groups, ".") ? vpc.factories_config.attachment_groups :
|
||||
"${vpc.factory_basepath}/${vpc.factories_config.attachment_groups}",
|
||||
"${vpc.factory_basepath}/attachment-groups"
|
||||
),
|
||||
"**/*.yaml"
|
||||
), []) :
|
||||
"${vpc_key}-${replace(f, ".yaml", "")}" => {
|
||||
vpc_key = vpc_key
|
||||
filename = f
|
||||
path = try(
|
||||
startswith(vpc.factories_config.attachment_groups, "/") || startswith(vpc.factories_config.attachment_groups, ".")
|
||||
? "${vpc.factories_config.attachment_groups}/${f}"
|
||||
: "${vpc.factory_basepath}/${vpc.factories_config.attachment_groups}/${f}",
|
||||
"${vpc.factory_basepath}/attachment-groups/${f}"
|
||||
)
|
||||
}
|
||||
}
|
||||
]...),
|
||||
{}
|
||||
)
|
||||
_attachment_groups_preprocess = {
|
||||
for k, v in local._attachment_groups_files : k => merge(
|
||||
{
|
||||
project_id = local.vpcs[v.vpc_key].project_id
|
||||
},
|
||||
try(yamldecode(file(v.path)), {}),
|
||||
{
|
||||
key = k
|
||||
vpc_key = v.vpc_key
|
||||
}
|
||||
)
|
||||
}
|
||||
attachment_groups = {
|
||||
for k, v in local._attachment_groups_preprocess : k => merge(v, {
|
||||
name = try(v.name, k)
|
||||
intent = try(v.intent, { availability_sla = "NO_SLA" })
|
||||
})
|
||||
}
|
||||
|
||||
ctx_attachment_groups = {
|
||||
for k, v in local.attachment_groups : "${v.vpc_key}/${v.name}" => k
|
||||
}
|
||||
|
||||
ctx_vlan_attachments = {
|
||||
for k, v in local.vlan_attachments : "${v.vpc_key}/${try(v.name, k)}" => k
|
||||
}
|
||||
|
||||
# Gathers all members for each attachment group. Membership can be defined
|
||||
# in two ways:
|
||||
# 1. From the VLAN attachment's config via the `attachment_group` attribute.
|
||||
# 2. From the attachment group's config via the `attachments` map.
|
||||
_attachment_groups_attachments = {
|
||||
for g_key, g_config in local.attachment_groups : g_key =>
|
||||
concat(
|
||||
[
|
||||
for a_key, a_config in local.vlan_attachments : {
|
||||
name = try(a_config.name, a_config.key)
|
||||
attachment = module.vlan-attachments[a_key].id
|
||||
}
|
||||
if try(
|
||||
lookup(local.ctx_attachment_groups, replace(a_config.attachment_group, "$attachment_groups:", ""), a_config.attachment_group),
|
||||
null
|
||||
) == g_key || (try(a_config.attachment_group, null) == g_config.name && a_config.vpc_key == g_config.vpc_key)
|
||||
],
|
||||
[
|
||||
for a in values(try(g_config.attachments, {})) : {
|
||||
name = a.name
|
||||
attachment = try(
|
||||
module.vlan-attachments[lookup(local.ctx_vlan_attachments, replace(a.attachment, "$vlan_attachments:", ""), a.attachment)].id,
|
||||
a.attachment
|
||||
)
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module "vlan-attachments" {
|
||||
@@ -95,3 +176,28 @@ module "vlan-attachments" {
|
||||
}
|
||||
depends_on = [module.vpc-factory]
|
||||
}
|
||||
|
||||
resource "google_compute_interconnect_attachment_group" "default" {
|
||||
for_each = local.attachment_groups
|
||||
project = lookup(
|
||||
local.ctx_projects.project_ids,
|
||||
replace(each.value.project_id, "$project_ids:", ""),
|
||||
each.value.project_id
|
||||
)
|
||||
name = each.value.name
|
||||
description = try(each.value.description, "Terraform-managed.")
|
||||
|
||||
intent {
|
||||
availability_sla = try(each.value.intent.availability_sla, "NO_SLA")
|
||||
}
|
||||
|
||||
dynamic "attachments" {
|
||||
for_each = local._attachment_groups_attachments[each.key]
|
||||
content {
|
||||
name = attachments.value.name
|
||||
attachment = attachments.value.attachment
|
||||
}
|
||||
}
|
||||
|
||||
depends_on = [module.vlan-attachments]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"$id": "https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/blob/master/fast/stages/2-networking/schemas/attachment-groups.schema.json",
|
||||
"title": "Attachment Groups schema",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"project_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"intent": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"availability_sla": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"NO_SLA",
|
||||
"PRODUCTION_NON_CRITICAL",
|
||||
"PRODUCTION_CRITICAL",
|
||||
"AVAILABILITY_SLA_UNSPECIFIED"
|
||||
],
|
||||
"default": "NO_SLA"
|
||||
}
|
||||
}
|
||||
},
|
||||
"attachments": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"patternProperties": {
|
||||
"^[a-zA-Z0-9-_]+$": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"name",
|
||||
"attachment"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"attachment": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
fast/stages/2-networking/schemas/attachment-groups.schema.md
Normal file
23
fast/stages/2-networking/schemas/attachment-groups.schema.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Attachment Groups schema
|
||||
|
||||
<!-- markdownlint-disable MD036 -->
|
||||
|
||||
## Properties
|
||||
|
||||
*additional properties: false*
|
||||
|
||||
- **name**: *string*
|
||||
- **project_id**: *string*
|
||||
- **description**: *string*
|
||||
- **intent**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **availability_sla**: *string*
|
||||
<br>*default: NO_SLA*, *enum: ['NO_SLA', 'PRODUCTION_NON_CRITICAL', 'PRODUCTION_CRITICAL', 'AVAILABILITY_SLA_UNSPECIFIED']*
|
||||
- **attachments**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **`^[a-zA-Z0-9-_]+$`**: *object*
|
||||
<br>*additional properties: false*
|
||||
- ⁺**name**: *string*
|
||||
- ⁺**attachment**: *string*
|
||||
|
||||
## Definitions
|
||||
@@ -13,6 +13,9 @@
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"attachment_group": {
|
||||
"type": "string"
|
||||
},
|
||||
"dedicated_interconnect_config": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*additional properties: false*
|
||||
|
||||
- **admin_enabled**: *boolean*
|
||||
- **attachment_group**: *string*
|
||||
- **dedicated_interconnect_config**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **bandwidth**: *string*
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
"firewall_rules": {
|
||||
"type": "string"
|
||||
},
|
||||
"attachment_groups": {
|
||||
"type": "string"
|
||||
},
|
||||
"subnets": {
|
||||
"type": "string"
|
||||
},
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
- **factories_config**: *object*
|
||||
<br>*additional properties: false*
|
||||
- **firewall_rules**: *string*
|
||||
- **attachment_groups**: *string*
|
||||
- **subnets**: *string*
|
||||
- **vlan_attachments**: *string*
|
||||
- **vpns**: *string*
|
||||
|
||||
Reference in New Issue
Block a user