From d20a078134f5e36babfcae7b7241bd4126423199 Mon Sep 17 00:00:00 2001 From: Julio Castillo Date: Fri, 12 May 2023 16:20:38 +0200 Subject: [PATCH 1/4] Cloud NAT rules support --- modules/net-cloudnat/README.md | 68 +++++++++++++++---- modules/net-cloudnat/main.tf | 14 +++- modules/net-cloudnat/variables.tf | 39 +++++------ .../modules/net_cloudnat/examples/rules.yaml | 55 +++++++++++++++ 4 files changed, 143 insertions(+), 33 deletions(-) create mode 100644 tests/modules/net_cloudnat/examples/rules.yaml diff --git a/modules/net-cloudnat/README.md b/modules/net-cloudnat/README.md index f186b58b..637d5cb8 100644 --- a/modules/net-cloudnat/README.md +++ b/modules/net-cloudnat/README.md @@ -2,7 +2,7 @@ Simple Cloud NAT management, with optional router creation. -## Example +## Basic Example ```hcl module "nat" { @@ -14,25 +14,67 @@ module "nat" { } # tftest modules=1 resources=2 ``` + +# Reserved IPs and custom rules + +```hcl +module "addresses" { + source = "./fabric/modules/net-address" + project_id = "my-project" + external_addresses = { + a1 = "europe-west1" + a2 = "europe-west1" + a3 = "europe-west1" + } +} + +module "nat" { + source = "./fabric/modules/net-cloudnat" + project_id = "my-project" + region = "europe-west1" + name = "nat" + router_network = "my-vpc" + addresses = [ + module.addresses.external_addresses["a1"].self_link, + module.addresses.external_addresses["a3"].self_link + ] + + config_port_allocation = { + enable_endpoint_independent_mapping = false + } + + rules = [ + { + description = "rule1" + match = "destination.ip == '8.8.8.8'" + source_ips = [ + module.addresses.external_addresses["a2"].self_link + ] + } + ] +} +# tftest modules=2 resources=5 inventory=rules.yaml +``` ## Variables | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [config_port_allocation](variables.tf#L23) | Configuration for how to assign ports to virtual machines. min_ports_per_vm and max_ports_per_vm have no effect unless enable_dynamic_port_allocation is set to 'true'. | object({…} | ✓ | | -| [name](variables.tf#L73) | Name of the Cloud NAT resource. | string | ✓ | | -| [project_id](variables.tf#L78) | Project where resources will be created. | string | ✓ | | -| [region](variables.tf#L83) | Region where resources will be created. | string | ✓ | | +| [name](variables.tf#L63) | Name of the Cloud NAT resource. | string | ✓ | | +| [project_id](variables.tf#L68) | Project where resources will be created. | string | ✓ | | +| [region](variables.tf#L73) | Region where resources will be created. | string | ✓ | | | [addresses](variables.tf#L17) | Optional list of external address self links. | list(string) | | [] | -| [config_source_subnets](variables.tf#L45) | Subnetwork configuration (ALL_SUBNETWORKS_ALL_IP_RANGES, ALL_SUBNETWORKS_ALL_PRIMARY_IP_RANGES, LIST_OF_SUBNETWORKS). | string | | "ALL_SUBNETWORKS_ALL_IP_RANGES" | -| [config_timeouts](variables.tf#L51) | Timeout configurations. | object({…}) | | {…} | -| [logging_filter](variables.tf#L67) | Enables logging if not null, value is one of 'ERRORS_ONLY', 'TRANSLATIONS_ONLY', 'ALL'. | string | | null | -| [router_asn](variables.tf#L88) | Router ASN used for auto-created router. | number | | 64514 | -| [router_create](variables.tf#L94) | Create router. | bool | | true | -| [router_name](variables.tf#L100) | Router name, leave blank if router will be created to use auto generated name. | string | | null | -| [router_network](variables.tf#L106) | Name of the VPC used for auto-created router. | string | | null | -| [subnetworks](variables.tf#L112) | Subnetworks to NAT, only used when config_source_subnets equals LIST_OF_SUBNETWORKS. | list(object({…})) | | [] | +| [config_port_allocation](variables.tf#L23) | Configuration for how to assign ports to virtual machines. min_ports_per_vm and max_ports_per_vm have no effect unless enable_dynamic_port_allocation is set to 'true'. | object({…}) | | {} | +| [config_source_subnets](variables.tf#L39) | Subnetwork configuration (ALL_SUBNETWORKS_ALL_IP_RANGES, ALL_SUBNETWORKS_ALL_PRIMARY_IP_RANGES, LIST_OF_SUBNETWORKS). | string | | "ALL_SUBNETWORKS_ALL_IP_RANGES" | +| [config_timeouts](variables.tf#L45) | Timeout configurations. | object({…}) | | {} | +| [logging_filter](variables.tf#L57) | Enables logging if not null, value is one of 'ERRORS_ONLY', 'TRANSLATIONS_ONLY', 'ALL'. | string | | null | +| [router_asn](variables.tf#L78) | Router ASN used for auto-created router. | number | | 64514 | +| [router_create](variables.tf#L84) | Create router. | bool | | true | +| [router_name](variables.tf#L90) | Router name, leave blank if router will be created to use auto generated name. | string | | null | +| [router_network](variables.tf#L96) | Name of the VPC used for auto-created router. | string | | null | +| [rules](variables.tf#L102) | List of rules associated with this NAT. | list(object({…})) | | [] | +| [subnetworks](variables.tf#L113) | Subnetworks to NAT, only used when config_source_subnets equals LIST_OF_SUBNETWORKS. | list(object({…})) | | [] | ## Outputs diff --git a/modules/net-cloudnat/main.tf b/modules/net-cloudnat/main.tf index 63209d05..68613c4d 100644 --- a/modules/net-cloudnat/main.tf +++ b/modules/net-cloudnat/main.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,5 +63,17 @@ resource "google_compute_router_nat" "nat" { secondary_ip_range_names = subnetwork.value.secondary_ranges } } + + dynamic "rules" { + for_each = { for i, r in var.rules : i => r } + content { + rule_number = rules.key + description = rules.value.description + match = rules.value.match + action { + source_nat_active_ips = rules.value.source_ips + } + } + } } diff --git a/modules/net-cloudnat/variables.tf b/modules/net-cloudnat/variables.tf index 97b03b27..abf06415 100644 --- a/modules/net-cloudnat/variables.tf +++ b/modules/net-cloudnat/variables.tf @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2023 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,14 +28,8 @@ variable "config_port_allocation" { min_ports_per_vm = optional(number, 64) max_ports_per_vm = optional(number, 65536) }) - - default = { - enable_endpoint_independent_mapping = true - enable_dynamic_port_allocation = false - min_ports_per_vm = 64 - max_ports_per_vm = 65536 - } - + default = {} + nullable = false validation { condition = var.config_port_allocation.enable_dynamic_port_allocation ? var.config_port_allocation.enable_endpoint_independent_mapping == false : true error_message = "You must set enable_endpoint_independent_mapping to false to set enable_dynamic_port_allocation to true." @@ -51,17 +45,13 @@ variable "config_source_subnets" { variable "config_timeouts" { description = "Timeout configurations." type = object({ - icmp = number - tcp_established = number - tcp_transitory = number - udp = number + icmp = optional(number, 30) + tcp_established = optional(number, 1200) + tcp_transitory = optional(number, 30) + udp = optional(number, 30) }) - default = { - icmp = 30 - tcp_established = 1200 - tcp_transitory = 30 - udp = 30 - } + default = {} + nullable = false } variable "logging_filter" { @@ -109,6 +99,17 @@ variable "router_network" { default = null } +variable "rules" { + description = "List of rules associated with this NAT." + type = list(object({ + description = optional(string), + match = string + source_ips = list(string) + })) + default = [] + nullable = false +} + variable "subnetworks" { description = "Subnetworks to NAT, only used when config_source_subnets equals LIST_OF_SUBNETWORKS." type = list(object({ diff --git a/tests/modules/net_cloudnat/examples/rules.yaml b/tests/modules/net_cloudnat/examples/rules.yaml new file mode 100644 index 00000000..62efd1b3 --- /dev/null +++ b/tests/modules/net_cloudnat/examples/rules.yaml @@ -0,0 +1,55 @@ +# Copyright 2023 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. + +values: + module.addresses.google_compute_address.external["a1"]: + address_type: EXTERNAL + name: a1 + project: my-project + region: europe-west1 + module.addresses.google_compute_address.external["a2"]: + address_type: EXTERNAL + name: a2 + project: my-project + region: europe-west1 + module.addresses.google_compute_address.external["a3"]: + address_type: EXTERNAL + name: a3 + project: my-project + region: europe-west1 + module.nat.google_compute_router.router[0]: + name: nat-nat + network: my-vpc + project: my-project + region: europe-west1 + module.nat.google_compute_router_nat.nat: + enable_dynamic_port_allocation: false + enable_endpoint_independent_mapping: false + icmp_idle_timeout_sec: 30 + name: nat + nat_ip_allocate_option: MANUAL_ONLY + project: my-project + region: europe-west1 + router: nat-nat + rules: + - action: + - source_nat_drain_ips: [] + description: rule1 + match: destination.ip == '8.8.8.8' + rule_number: 0 + +counts: + google_compute_address: 3 + google_compute_router: 1 + google_compute_router_nat: 1 From dd1e5dc4635eec7959539da0e5e275501cf55852 Mon Sep 17 00:00:00 2001 From: Manuel Aller Date: Sun, 14 May 2023 10:29:24 -0300 Subject: [PATCH 2/4] =?UTF-8?q?added=20the=20export=5Fpublic=5Fip=5Froutes?= =?UTF-8?q?=20variable=20in=20the=20net-vpc-peering=20mod=E2=80=A6=20(#137?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * added the export_public_ip_routes variable in the net-vpc-peering module to control the google_compute_network_peering resource created * adding period to the variable description --- modules/net-vpc-peering/README.md | 9 +++++---- modules/net-vpc-peering/main.tf | 24 +++++++++++++----------- modules/net-vpc-peering/variables.tf | 6 ++++++ 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/modules/net-vpc-peering/README.md b/modules/net-vpc-peering/README.md index 0555b994..b9595c1d 100644 --- a/modules/net-vpc-peering/README.md +++ b/modules/net-vpc-peering/README.md @@ -46,12 +46,13 @@ module "peering-a-c" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [local_network](variables.tf#L30) | Resource link of the network to add a peering to. | string | ✓ | | -| [peer_network](variables.tf#L41) | Resource link of the peer network. | string | ✓ | | +| [local_network](variables.tf#L36) | Resource link of the network to add a peering to. | string | ✓ | | +| [peer_network](variables.tf#L47) | Resource link of the peer network. | string | ✓ | | | [export_local_custom_routes](variables.tf#L18) | Export custom routes to peer network from local network. | bool | | false | | [export_peer_custom_routes](variables.tf#L24) | Export custom routes to local network from peer network. | bool | | false | -| [peer_create_peering](variables.tf#L35) | Create the peering on the remote side. If false, only the peering from this network to the remote network is created. | bool | | true | -| [prefix](variables.tf#L46) | Optional name prefix for the network peerings. | string | | null | +| [export_public_ip_routes](variables.tf#L30) | Export subnet routes with public ip. | bool | | true | +| [peer_create_peering](variables.tf#L41) | Create the peering on the remote side. If false, only the peering from this network to the remote network is created. | bool | | true | +| [prefix](variables.tf#L52) | Optional name prefix for the network peerings. | string | | null | ## Outputs diff --git a/modules/net-vpc-peering/main.tf b/modules/net-vpc-peering/main.tf index f705df71..204b5015 100644 --- a/modules/net-vpc-peering/main.tf +++ b/modules/net-vpc-peering/main.tf @@ -21,20 +21,22 @@ locals { } resource "google_compute_network_peering" "local_network_peering" { - name = "${local.prefix}${local.local_network_name}-${local.peer_network_name}" - network = var.local_network - peer_network = var.peer_network - export_custom_routes = var.export_local_custom_routes - import_custom_routes = var.export_peer_custom_routes + name = "${local.prefix}${local.local_network_name}-${local.peer_network_name}" + network = var.local_network + peer_network = var.peer_network + export_custom_routes = var.export_local_custom_routes + import_custom_routes = var.export_peer_custom_routes + export_subnet_routes_with_public_ip = var.export_public_ip_routes } resource "google_compute_network_peering" "peer_network_peering" { - count = var.peer_create_peering ? 1 : 0 - name = "${local.prefix}${local.peer_network_name}-${local.local_network_name}" - network = var.peer_network - peer_network = var.local_network - export_custom_routes = var.export_peer_custom_routes - import_custom_routes = var.export_local_custom_routes + count = var.peer_create_peering ? 1 : 0 + name = "${local.prefix}${local.peer_network_name}-${local.local_network_name}" + network = var.peer_network + peer_network = var.local_network + export_custom_routes = var.export_peer_custom_routes + import_custom_routes = var.export_local_custom_routes + export_subnet_routes_with_public_ip = var.export_public_ip_routes depends_on = [google_compute_network_peering.local_network_peering] } diff --git a/modules/net-vpc-peering/variables.tf b/modules/net-vpc-peering/variables.tf index 8f5f15f6..408d1bc2 100644 --- a/modules/net-vpc-peering/variables.tf +++ b/modules/net-vpc-peering/variables.tf @@ -27,6 +27,12 @@ variable "export_peer_custom_routes" { default = false } +variable "export_public_ip_routes" { + description = "Export subnet routes with public ip." + type = bool + default = true +} + variable "local_network" { description = "Resource link of the network to add a peering to." type = string From 7861ea74b863acf074833c10fb2c60b05db31539 Mon Sep 17 00:00:00 2001 From: Alex Ostapenko Date: Mon, 15 May 2023 12:20:33 +0200 Subject: [PATCH 3/4] fixed permissions for security stage SA (#1376) it should be able to use automation project as a quota project, hence it needs `serviceusage.serviceUsageConsumer` role --- fast/stages/1-resman/branch-security.tf | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fast/stages/1-resman/branch-security.tf b/fast/stages/1-resman/branch-security.tf index 8e638a1a..31a833dc 100644 --- a/fast/stages/1-resman/branch-security.tf +++ b/fast/stages/1-resman/branch-security.tf @@ -59,6 +59,11 @@ module "branch-security-sa" { try(module.branch-security-sa-cicd.0.iam_email, null) ]) } + iam_project_roles = { + (var.automation.project_id) = [ + "roles/serviceusage.serviceUsageConsumer", + ] + } iam_storage_roles = { (var.automation.outputs_bucket) = ["roles/storage.objectAdmin"] } From f5b10fa3da4997c3b0803e4b517a97aa6cd78d9c Mon Sep 17 00:00:00 2001 From: Natalia Strelkova Date: Mon, 15 May 2023 12:55:43 +0200 Subject: [PATCH 4/4] Fixed home path --- fast/stages/3-project-factory/dev/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fast/stages/3-project-factory/dev/README.md b/fast/stages/3-project-factory/dev/README.md index e2a75c2f..b9eb9c76 100644 --- a/fast/stages/3-project-factory/dev/README.md +++ b/fast/stages/3-project-factory/dev/README.md @@ -62,12 +62,12 @@ The commands to link or copy the provider and terraform variable files can be ea # copy and paste the following commands for '3-project-factory' -ln -s /home/ludomagno/fast-config/providers/3-project-factory-providers.tf ./ -ln -s /home/ludomagno/fast-config/tfvars/globals.auto.tfvars.json ./ -ln -s /home/ludomagno/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ -ln -s /home/ludomagno/fast-config/tfvars/1-resman.auto.tfvars.json ./ -ln -s /home/ludomagno/fast-config/tfvars/2-networking.auto.tfvars.json ./ -ln -s /home/ludomagno/fast-config/tfvars/2-security.auto.tfvars.json ./ +ln -s ~/fast-config/providers/3-project-factory-providers.tf ./ +ln -s ~/fast-config/tfvars/globals.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/0-bootstrap.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/1-resman.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/2-networking.auto.tfvars.json ./ +ln -s ~/fast-config/tfvars/2-security.auto.tfvars.json ./ ``` ```bash