diff --git a/fast/stages/2-networking/README.md b/fast/stages/2-networking/README.md index f16324d60..fbff5c7ee 100644 --- a/fast/stages/2-networking/README.md +++ b/fast/stages/2-networking/README.md @@ -187,7 +187,7 @@ Note that the stage doesn't force you to create projects; factories also allow y The VPC factory allows for the definition of an arbitrary number of VPCs, along with their subnets, routes, firewall rules, and connectivity settings, all through YAML files. -VPCs are defined in `.config.yaml` files within the `vpcs/[vpc-name]` directory of a dataset. This file contains the VPC's main configuration. Subnets, firewall rules, and VPNs are defined in subdirectories within each VPC's folder. +VPCs are defined in `.config.yaml` files within the `vpcs/[vpc-name]` directory of a dataset. This file contains the VPC's main configuration. Subnets, firewall rules, VPNs, and VLAN attachments are defined in subdirectories within each VPC's folder. An optional `addresses.yaml` file can be placed in the VPC directory to define arbitrary addresses (external, internal, global, PSC). ### DNS @@ -372,6 +372,7 @@ Internally created resources are mapped to context namespaces, and use specific | name | description | modules | resources | |---|---|---|---| +| [factory-addresses.tf](./factory-addresses.tf) | Arbitrary addresses factory. | net-address | | | [factory-cloudnat.tf](./factory-cloudnat.tf) | Cloud NAT factory. | net-address · net-cloudnat | | | [factory-dns.tf](./factory-dns.tf) | DNS zones and RPZ factory. | dns · dns-response-policy | | | [factory-firewall-policies.tf](./factory-firewall-policies.tf) | Firewall policies factory. | net-firewall-policy | | diff --git a/fast/stages/2-networking/factory-addresses.tf b/fast/stages/2-networking/factory-addresses.tf new file mode 100644 index 000000000..872310068 --- /dev/null +++ b/fast/stages/2-networking/factory-addresses.tf @@ -0,0 +1,38 @@ +/** + * Copyright 2026 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +# tfdoc:file:description Arbitrary addresses factory. + +module "vpc-addresses" { + source = "../../../modules/net-address" + for_each = { for k, v in local.vpcs : k => v if length(v.addresses) > 0 } + + project_id = each.value.project_id + + external_addresses = try(each.value.addresses.external, {}) + global_addresses = try(each.value.addresses.global, {}) + internal_addresses = try(each.value.addresses.internal, {}) + psa_addresses = try(each.value.addresses.psa, {}) + psc_addresses = try(each.value.addresses.psc, {}) + network_attachments = try(each.value.addresses.network_attachments, {}) + + context = { + locations = local.ctx.locations + networks = local.ctx_vpcs.self_links + project_ids = local.ctx_projects.project_ids + subnets = local.ctx_vpcs.subnets_by_vpc + } +} diff --git a/fast/stages/2-networking/factory-vpcs.tf b/fast/stages/2-networking/factory-vpcs.tf index a580a1ced..f8faab097 100644 --- a/fast/stages/2-networking/factory-vpcs.tf +++ b/fast/stages/2-networking/factory-vpcs.tf @@ -27,6 +27,7 @@ locals { { factory_dirname = dirname(f) factory_basepath = "${local.paths.vpcs}/${dirname(f)}" + addresses = try(yamldecode(file("${local.paths.vpcs}/${dirname(f)}/addresses.yaml")), {}) } ) ] diff --git a/fast/stages/2-networking/schemas/addresses.schema.json b/fast/stages/2-networking/schemas/addresses.schema.json new file mode 100644 index 000000000..3aea00deb --- /dev/null +++ b/fast/stages/2-networking/schemas/addresses.schema.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Addresses", + "type": "object", + "additionalProperties": false, + "properties": { + "external": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "required": ["region"], + "properties": { + "region": { "type": "string" }, + "description": { "type": "string" }, + "ipv6": { + "type": "object", + "additionalProperties": false, + "required": ["endpoint_type"], + "properties": { + "endpoint_type": { "type": "string", "enum": ["NETLB", "VM"] } + } + }, + "labels": { "type": "object", "additionalProperties": { "type": "string" } }, + "name": { "type": "string" }, + "subnetwork": { "type": "string" }, + "tier": { "type": "string", "enum": ["PREMIUM", "STANDARD"] } + } + } + }, + "global": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "description": { "type": "string" }, + "ipv6": { "type": "object", "additionalProperties": true }, + "name": { "type": "string" } + } + } + }, + "internal": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "required": ["region", "subnetwork"], + "properties": { + "region": { "type": "string" }, + "subnetwork": { "type": "string" }, + "address": { "type": "string" }, + "description": { "type": "string" }, + "labels": { "type": "object", "additionalProperties": { "type": "string" } }, + "name": { "type": "string" }, + "purpose": { "type": "string" }, + "tier": { "type": "string" } + } + } + }, + "psa": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "required": ["address", "network", "prefix_length"], + "properties": { + "address": { "type": "string" }, + "network": { "type": "string" }, + "prefix_length": { "type": "number" }, + "description": { "type": "string" }, + "name": { "type": "string" } + } + } + }, + "psc": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "properties": { + "address": { "type": "string" }, + "description": { "type": "string" }, + "name": { "type": "string" }, + "network": { "type": "string" }, + "region": { "type": "string" }, + "subnet_self_link": { "type": "string" }, + "service_attachment": { + "type": "object", + "additionalProperties": false, + "required": ["psc_service_attachment_link"], + "properties": { + "psc_service_attachment_link": { "type": "string" }, + "global_access": { "type": "boolean" } + } + } + } + } + }, + "network_attachments": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "required": ["subnet_self_link"], + "properties": { + "subnet_self_link": { "type": "string" }, + "automatic_connection": { "type": "boolean" }, + "description": { "type": "string" }, + "producer_accept_lists": { "type": "array", "items": { "type": "string" } }, + "producer_reject_lists": { "type": "array", "items": { "type": "string" } } + } + } + } + } +} diff --git a/fast/stages/2-networking/schemas/addresses.schema.md b/fast/stages/2-networking/schemas/addresses.schema.md new file mode 100644 index 000000000..5b13669b4 --- /dev/null +++ b/fast/stages/2-networking/schemas/addresses.schema.md @@ -0,0 +1,22 @@ +# Addresses + + + +## Properties + +*additional properties: false* + +- **external**: *object* +
*additional properties: object* +- **global**: *object* +
*additional properties: object* +- **internal**: *object* +
*additional properties: object* +- **psa**: *object* +
*additional properties: object* +- **psc**: *object* +
*additional properties: object* +- **network_attachments**: *object* +
*additional properties: object* + +## Definitions diff --git a/tests/fast/stages/s2_networking/addresses.tfvars b/tests/fast/stages/s2_networking/addresses.tfvars new file mode 100644 index 000000000..ea72087f4 --- /dev/null +++ b/tests/fast/stages/s2_networking/addresses.tfvars @@ -0,0 +1,22 @@ +automation = { outputs_bucket = "test" } +billing_account = { id = "000000-111111-222222" } +factories_config = { + dataset = "./data-testaddresses" + paths = { defaults = "defaults.yaml" } +} +folder_ids = { + "networking" = "folders/12345678" + "networking/prod" = "folders/23456789" + "networking/dev" = "folders/34567890" +} +organization = { domain = "fast.example.com", id = 123456789012, customer_id = "C00000000" } +prefix = "fast" +service_accounts = { + "iac-0/iac-pf-rw" = "iac-pf-rw@test.iam.gserviceaccount.com" + "iac-0/iac-pf-ro" = "iac-pf-ro@test.iam.gserviceaccount.com" +} +storage_buckets = { "iac-0/iac-outputs" = "test" } +tag_values = { + "environment/development" = "tagValues/12345" + "environment/production" = "tagValues/12346" +} diff --git a/tests/fast/stages/s2_networking/addresses.yaml b/tests/fast/stages/s2_networking/addresses.yaml new file mode 100644 index 000000000..d4735e01f --- /dev/null +++ b/tests/fast/stages/s2_networking/addresses.yaml @@ -0,0 +1,27 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +counts: + google_compute_address: 4 + google_compute_forwarding_rule: 1 + google_compute_global_address: 3 + google_compute_global_forwarding_rule: 1 + google_compute_network: 1 + google_compute_network_attachment: 1 + google_compute_route: 3 + google_compute_subnetwork: 1 + google_storage_bucket_object: 2 + modules: 4 + resources: 19 + terraform_data: 2 diff --git a/tests/fast/stages/s2_networking/data-testaddresses/defaults.yaml b/tests/fast/stages/s2_networking/data-testaddresses/defaults.yaml new file mode 100644 index 000000000..ee767201f --- /dev/null +++ b/tests/fast/stages/s2_networking/data-testaddresses/defaults.yaml @@ -0,0 +1,30 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# yaml-language-server: $schema=../../schemas/defaults.schema.json +context: + locations: + primary: europe-west1 + secondary: europe-west3 + iam_principals: {} +projects: + defaults: + locations: + storage: eu +vpcs: + auto_create_subnetworks: false + delete_default_routes_on_create: true + mtu: 1500 +output_files: + storage_bucket: $storage_buckets:iac-0/iac-outputs diff --git a/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/.config.yaml b/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/.config.yaml new file mode 100644 index 000000000..b97e563cd --- /dev/null +++ b/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/.config.yaml @@ -0,0 +1,18 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# yaml-language-server: $schema=../../../../schemas/vpc.schema.json +project_id: $project_ids:net-core-0 +name: core-0 +delete_default_routes_on_create: true diff --git a/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/addresses.yaml b/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/addresses.yaml new file mode 100644 index 000000000..953824475 --- /dev/null +++ b/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/addresses.yaml @@ -0,0 +1,57 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# yaml-language-server: $schema=../../../../schemas/addresses.schema.json + +external: + test-ext: + region: $locations:primary + +global: + test-global: {} + +internal: + test-int: + region: $locations:primary + subnetwork: $subnets:core/europe-west1/core-default + +psc: + # 1. Regional PSC Address only + psc-reg: + region: $locations:primary + subnet_self_link: $subnets:core/europe-west1/core-default + + # 2. Regional PSC Address + Forwarding Rule + psc-reg-fr: + region: $locations:primary + subnet_self_link: $subnets:core/europe-west1/core-default + service_attachment: + psc_service_attachment_link: projects/producer-project/regions/europe-west1/serviceAttachments/my-sa + + # 3. Global PSC Address only + psc-global: + network: $networks:core + address: "10.0.0.32" + + # 4. Global PSC Address + Forwarding Rule + psc-global-fr: + network: $networks:core + address: "10.0.0.33" + service_attachment: + psc_service_attachment_link: projects/producer-project/global/serviceAttachments/my-global-sa + +network_attachments: + # 5. PSC Network Attachment (Producer side) + test-na: + subnet_self_link: projects/test-project/regions/europe-west1/subnetworks/core-default diff --git a/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/subnets/core-default.yaml b/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/subnets/core-default.yaml new file mode 100644 index 000000000..3ed79aea0 --- /dev/null +++ b/tests/fast/stages/s2_networking/data-testaddresses/vpcs/core/subnets/core-default.yaml @@ -0,0 +1,19 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# yaml-language-server: $schema=../../../../../schemas/subnet.schema.json +name: core-default +region: $locations:primary +ip_cidr_range: 10.71.0.0/24 +description: Default primary-region subnet for core diff --git a/tests/fast/stages/s2_networking/tftest.yaml b/tests/fast/stages/s2_networking/tftest.yaml index c4aea7a8a..10f3c4945 100644 --- a/tests/fast/stages/s2_networking/tftest.yaml +++ b/tests/fast/stages/s2_networking/tftest.yaml @@ -35,3 +35,8 @@ tests: extra_dirs: - ../../../tests/fast/stages/s2_networking/data-testvlan vpns: + addresses: + inventory: + - addresses.yaml + extra_dirs: + - ../../../tests/fast/stages/s2_networking/data-testaddresses diff --git a/tests/fast/stages/s2_networking/vlan_attachments.yaml b/tests/fast/stages/s2_networking/vlan_attachments.yaml index a014db5fd..cab8cfd48 100644 --- a/tests/fast/stages/s2_networking/vlan_attachments.yaml +++ b/tests/fast/stages/s2_networking/vlan_attachments.yaml @@ -4,7 +4,7 @@ # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # -# http://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, @@ -155,7 +155,6 @@ values: content_language: null contexts: [] customer_encryption: [] - deletion_policy: null detect_md5hash: null event_based_hold: null force_empty_content_type: null @@ -173,7 +172,6 @@ values: module.projects.module.projects["net-core-0"].google_project.project[0]: auto_create_network: false billing_account: 000000-111111-222222 - deletion_policy: DELETE effective_labels: goog-terraform-provisioned: 'true' folder_id: '12345678' @@ -718,4 +716,3 @@ outputs: hub: {} subnet_self_links: __missing__ vpc_self_links: __missing__ -