From a23b3d62aecd337f4b63ebad5e05f7da7571ac0f Mon Sep 17 00:00:00 2001 From: Luca Prete Date: Sat, 21 Oct 2023 18:19:18 +0200 Subject: [PATCH] net-lb-ext: add support for multiple forwarding rules (IPs) and dual-stack (IPv4/IPv6) --- modules/net-lb-ext/README.md | 121 ++++++++++++++---- modules/net-lb-ext/groups.tf | 2 +- modules/net-lb-ext/health-check.tf | 2 +- modules/net-lb-ext/main.tf | 26 ++-- modules/net-lb-ext/outputs.tf | 33 +++-- modules/net-lb-ext/variables.tf | 28 ++-- tests/modules/net_lb_ext/defaults.tfvars | 7 + tests/modules/net_lb_ext/defaults.yaml | 46 +++++++ tests/modules/net_lb_ext/dual-stack.tfvars | 15 +++ tests/modules/net_lb_ext/dual-stack.yaml | 23 ++++ .../modules/net_lb_ext/forwarding-rule.tfvars | 13 ++ tests/modules/net_lb_ext/forwarding-rule.yaml | 23 ++++ tests/modules/net_lb_ext/tftest.yaml | 20 +++ 13 files changed, 298 insertions(+), 61 deletions(-) create mode 100644 tests/modules/net_lb_ext/defaults.tfvars create mode 100644 tests/modules/net_lb_ext/defaults.yaml create mode 100644 tests/modules/net_lb_ext/dual-stack.tfvars create mode 100644 tests/modules/net_lb_ext/dual-stack.yaml create mode 100644 tests/modules/net_lb_ext/forwarding-rule.tfvars create mode 100644 tests/modules/net_lb_ext/forwarding-rule.yaml create mode 100644 tests/modules/net_lb_ext/tftest.yaml diff --git a/modules/net-lb-ext/README.md b/modules/net-lb-ext/README.md index a0f3bbcc..18d2859d 100644 --- a/modules/net-lb-ext/README.md +++ b/modules/net-lb-ext/README.md @@ -90,6 +90,78 @@ module "nlb" { # tftest modules=1 resources=4 ``` +### Mutiple forwarding rules + +You can add more forwarding rules to your load balancer and override some forwarding rules defaults, including the global access policy, the IP protocol, the IP version and ports. + +The example adds two forwarding rules: + +- the first one, called `nlb-test-vip-one` exposes an IPv4 address, it listens on all ports, and allows connections from any region. +- the second one, called `nlb-test-vip-two` exposes an IPv4 address, it listens on port 80 and allows connections from the same region only. + +```hcl +module "nlb" { + source = "./fabric/modules/net-lb-ext" + project_id = var.project_id + region = "europe-west1" + name = "nlb-test" + backends = [{ + group = module.nlb.groups.my-group.self_link + }] + forwarding_rules_config = { + vip-one = {} + vip-two = { + ports = [80] + } + } + group_configs = { + my-group = { + zone = "europe-west1-b" + instances = [ + "instance-1-self-link", + "instance-2-self-link" + ] + } + } +} +# tftest modules=1 resources=5 +``` + +### Dual stack (IPv4 and IPv6) + +Your load balancer can use a combination of either or both IPv4 and IPv6 forwarding rules. +In this example we set the load balancer to work as dual stack, meaning it exposes both an IPv4 and an IPv6 address. + +```hcl +module "nlb" { + source = "./fabric/modules/net-lb-ext" + project_id = var.project_id + region = "europe-west1" + name = "nlb-test" + backends = [{ + group = module.nlb.groups.my-group.self_link + }] + forwarding_rules_config = { + ipv4 = { + version = "IPV4" + } + ipv6 = { + version = "IPV6" + } + } + group_configs = { + my-group = { + zone = "europe-west1-b" + instances = [ + "instance-1-self-link", + "instance-2-self-link" + ] + } + } +} +# tftest modules=1 resources=5 +``` + ### End to end example This example spins up a simple HTTP server and combines four modules: @@ -136,12 +208,16 @@ module "nlb" { project_id = var.project_id region = "europe-west1" name = "nlb-test" - ports = [80] backends = [ for z, mod in module.instance-group : { group = mod.group.self_link } ] + forwarding_rules_config = { + "" = { + ports = [80] + } + } health_check_config = { http = { port = 80 @@ -155,19 +231,18 @@ module "nlb" { | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [name](variables.tf#L189) | Name used for all resources. | string | ✓ | | -| [project_id](variables.tf#L200) | Project id where resources will be created. | string | ✓ | | -| [region](variables.tf#L216) | GCP region. | string | ✓ | | -| [address](variables.tf#L17) | Optional IP address used for the forwarding rule. | string | | null | -| [backend_service_config](variables.tf#L23) | Backend service level configuration. | object({…}) | | {} | -| [backends](variables.tf#L72) | Load balancer backends. | list(object({…})) | | [] | -| [description](variables.tf#L83) | Optional description used for resources. | string | | "Terraform managed." | -| [group_configs](variables.tf#L89) | Optional unmanaged groups to create. Can be referenced in backends via outputs. | map(object({…})) | | {} | -| [health_check](variables.tf#L100) | Name of existing health check to use, disables auto-created health check. | string | | null | -| [health_check_config](variables.tf#L106) | Optional auto-created health check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | object({…}) | | {…} | -| [labels](variables.tf#L183) | Labels set on resources. | map(string) | | {} | -| [ports](variables.tf#L194) | Comma-separated ports, leave null to use all ports. | list(string) | | null | -| [protocol](variables.tf#L205) | IP protocol used, defaults to TCP. UDP or L3_DEFAULT can also be used. | string | | "TCP" | +| [name](variables.tf#L197) | Name used for all resources. | string | ✓ | | +| [project_id](variables.tf#L202) | Project id where resources will be created. | string | ✓ | | +| [region](variables.tf#L218) | GCP region. | string | ✓ | | +| [backend_service_config](variables.tf#L17) | Backend service level configuration. | object({…}) | | {} | +| [backends](variables.tf#L66) | Load balancer backends. | list(object({…})) | | [] | +| [description](variables.tf#L77) | Optional description used for resources. | string | | "Terraform managed." | +| [forwarding_rules_config](variables.tf#L83) | The optional forwarding rules configuration. | map(object({…})) | | {…} | +| [group_configs](variables.tf#L97) | Optional unmanaged groups to create. Can be referenced in backends via outputs. | map(object({…})) | | {} | +| [health_check](variables.tf#L108) | Name of existing health check to use, disables auto-created health check. | string | | null | +| [health_check_config](variables.tf#L114) | Optional auto-created health check configuration, use the output self-link to set it in the auto healing policy. Refer to examples for usage. | object({…}) | | {…} | +| [labels](variables.tf#L191) | Labels set on resources. | map(string) | | {} | +| [protocol](variables.tf#L207) | IP protocol used, defaults to TCP. UDP or L3_DEFAULT can also be used. | string | | "TCP" | ## Outputs @@ -176,13 +251,13 @@ module "nlb" { | [backend_service](outputs.tf#L17) | Backend resource. | | | [backend_service_id](outputs.tf#L22) | Backend id. | | | [backend_service_self_link](outputs.tf#L27) | Backend self link. | | -| [forwarding_rule](outputs.tf#L32) | Forwarding rule resource. | | -| [forwarding_rule_address](outputs.tf#L37) | Forwarding rule address. | | -| [forwarding_rule_self_link](outputs.tf#L42) | Forwarding rule self link. | | -| [group_self_links](outputs.tf#L47) | Optional unmanaged instance group self links. | | -| [groups](outputs.tf#L54) | Optional unmanaged instance group resources. | | -| [health_check](outputs.tf#L59) | Auto-created health-check resource. | | -| [health_check_self_id](outputs.tf#L64) | Auto-created health-check self id. | | -| [health_check_self_link](outputs.tf#L69) | Auto-created health-check self link. | | -| [id](outputs.tf#L74) | Fully qualified forwarding rule id. | | +| [forwarding_rule_addresses](outputs.tf#L32) | Forwarding rule addresses. | | +| [forwarding_rule_self_links](outputs.tf#L40) | Forwarding rule self links. | | +| [forwarding_rules](outputs.tf#L48) | Forwarding rule resources. | | +| [group_self_links](outputs.tf#L53) | Optional unmanaged instance group self links. | | +| [groups](outputs.tf#L60) | Optional unmanaged instance group resources. | | +| [health_check](outputs.tf#L65) | Auto-created health-check resource. | | +| [health_check_self_id](outputs.tf#L70) | Auto-created health-check self id. | | +| [health_check_self_link](outputs.tf#L75) | Auto-created health-check self link. | | +| [id](outputs.tf#L80) | Fully qualified forwarding rule ids. | | diff --git a/modules/net-lb-ext/groups.tf b/modules/net-lb-ext/groups.tf index f3fcaa82..3389fb17 100644 --- a/modules/net-lb-ext/groups.tf +++ b/modules/net-lb-ext/groups.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. diff --git a/modules/net-lb-ext/health-check.tf b/modules/net-lb-ext/health-check.tf index 08ea0164..d41a437d 100644 --- a/modules/net-lb-ext/health-check.tf +++ b/modules/net-lb-ext/health-check.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. diff --git a/modules/net-lb-ext/main.tf b/modules/net-lb-ext/main.tf index 68619b6b..fafa3649 100644 --- a/modules/net-lb-ext/main.tf +++ b/modules/net-lb-ext/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. @@ -24,20 +24,24 @@ locals { ) } -resource "google_compute_forwarding_rule" "default" { - provider = google-beta - project = var.project_id - region = var.region - name = var.name - description = var.description - ip_address = var.address - ip_protocol = var.protocol +resource "google_compute_forwarding_rule" "forwarding_rules" { + for_each = var.forwarding_rules_config + provider = google-beta + project = var.project_id + region = var.region + name = ( + each.key == "" ? var.name : "${var.name}-${each.key}" + ) + description = each.value.description + ip_address = each.value.address + ip_protocol = each.value.protocol + ip_version = each.value.ip_version backend_service = ( google_compute_region_backend_service.default.self_link ) load_balancing_scheme = "EXTERNAL" - ports = var.ports # "nnnnn" or "nnnnn,nnnnn,nnnnn" max 5 - all_ports = var.ports == null ? true : null + ports = each.value.ports # "nnnnn" or "nnnnn,nnnnn,nnnnn" max 5 + all_ports = each.value.ports == null ? true : null labels = var.labels # is_mirroring_collector = false } diff --git a/modules/net-lb-ext/outputs.tf b/modules/net-lb-ext/outputs.tf index f7bb5433..bd3f383a 100644 --- a/modules/net-lb-ext/outputs.tf +++ b/modules/net-lb-ext/outputs.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. @@ -29,19 +29,25 @@ output "backend_service_self_link" { value = google_compute_region_backend_service.default.self_link } -output "forwarding_rule" { - description = "Forwarding rule resource." - value = google_compute_forwarding_rule.default +output "forwarding_rule_addresses" { + description = "Forwarding rule addresses." + value = { + for k, v in google_compute_forwarding_rule.forwarding_rules + : k => v.ip_address + } } -output "forwarding_rule_address" { - description = "Forwarding rule address." - value = google_compute_forwarding_rule.default.ip_address +output "forwarding_rule_self_links" { + description = "Forwarding rule self links." + value = { + for k, v in google_compute_forwarding_rule.forwarding_rules + : k => v.self_link + } } -output "forwarding_rule_self_link" { - description = "Forwarding rule self link." - value = google_compute_forwarding_rule.default.self_link +output "forwarding_rules" { + description = "Forwarding rule resources." + value = google_compute_forwarding_rule.forwarding_rules } output "group_self_links" { @@ -72,6 +78,9 @@ output "health_check_self_link" { } output "id" { - description = "Fully qualified forwarding rule id." - value = google_compute_forwarding_rule.default.id + description = "Fully qualified forwarding rule ids." + value = { + for k, v in google_compute_forwarding_rule.forwarding_rules + : k => v.id + } } diff --git a/modules/net-lb-ext/variables.tf b/modules/net-lb-ext/variables.tf index d562e839..c9e16ae2 100644 --- a/modules/net-lb-ext/variables.tf +++ b/modules/net-lb-ext/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. @@ -14,12 +14,6 @@ * limitations under the License. */ -variable "address" { - description = "Optional IP address used for the forwarding rule." - type = string - default = null -} - variable "backend_service_config" { description = "Backend service level configuration." type = object({ @@ -86,6 +80,20 @@ variable "description" { default = "Terraform managed." } +variable "forwarding_rules_config" { + description = "The optional forwarding rules configuration." + type = map(object({ + address = optional(string) + description = optional(string) + ip_version = optional(string) + ports = optional(list(string), null) + protocol = optional(string, "TCP") + })) + default = { + "" = {} + } +} + variable "group_configs" { description = "Optional unmanaged groups to create. Can be referenced in backends via outputs." type = map(object({ @@ -191,12 +199,6 @@ variable "name" { type = string } -variable "ports" { - description = "Comma-separated ports, leave null to use all ports." - type = list(string) - default = null -} - variable "project_id" { description = "Project id where resources will be created." type = string diff --git a/tests/modules/net_lb_ext/defaults.tfvars b/tests/modules/net_lb_ext/defaults.tfvars new file mode 100644 index 00000000..2b34e7c9 --- /dev/null +++ b/tests/modules/net_lb_ext/defaults.tfvars @@ -0,0 +1,7 @@ +project_id = "my-project" +region = "europe-west1" +name = "nlb-test" +backends = [{ + group = "foo" + failover = false +}] diff --git a/tests/modules/net_lb_ext/defaults.yaml b/tests/modules/net_lb_ext/defaults.yaml new file mode 100644 index 00000000..d0d8ff7a --- /dev/null +++ b/tests/modules/net_lb_ext/defaults.yaml @@ -0,0 +1,46 @@ +# 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: + google_compute_forwarding_rule.forwarding_rules[""]: + all_ports: true + ip_protocol: TCP + labels: null + load_balancing_scheme: EXTERNAL + name: nlb-test + project: my-project + region: europe-west1 + google_compute_region_backend_service.default: + backend: + - balancing_mode: CONNECTION + capacity_scaler: null + description: Terraform managed. + failover: false + group: foo + max_connections: null + max_connections_per_endpoint: null + max_connections_per_instance: null + max_rate: null + max_rate_per_endpoint: null + max_rate_per_instance: null + max_utilization: null + load_balancing_scheme: EXTERNAL + name: nlb-test + project: my-project + protocol: UNSPECIFIED + region: europe-west1 + +counts: + google_compute_forwarding_rule: 1 + google_compute_region_backend_service: 1 diff --git a/tests/modules/net_lb_ext/dual-stack.tfvars b/tests/modules/net_lb_ext/dual-stack.tfvars new file mode 100644 index 00000000..3d0ebe0b --- /dev/null +++ b/tests/modules/net_lb_ext/dual-stack.tfvars @@ -0,0 +1,15 @@ +project_id = "my-project" +region = "europe-west1" +name = "nlb-test" +backends = [{ + group = "foo" + failover = false +}] +forwarding_rules_config = { + ipv4 = { + ip_version = "IPV4" + } + ipv6 = { + ip_version = "IPV6" + } +} diff --git a/tests/modules/net_lb_ext/dual-stack.yaml b/tests/modules/net_lb_ext/dual-stack.yaml new file mode 100644 index 00000000..8caff192 --- /dev/null +++ b/tests/modules/net_lb_ext/dual-stack.yaml @@ -0,0 +1,23 @@ +# 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: + google_compute_forwarding_rule.forwarding_rules["ipv4"]: + ip_version: "IPV4" + google_compute_forwarding_rule.forwarding_rules["ipv6"]: + ip_version: "IPV6" + +counts: + google_compute_forwarding_rule: 2 + google_compute_region_backend_service: 1 diff --git a/tests/modules/net_lb_ext/forwarding-rule.tfvars b/tests/modules/net_lb_ext/forwarding-rule.tfvars new file mode 100644 index 00000000..9222e4a9 --- /dev/null +++ b/tests/modules/net_lb_ext/forwarding-rule.tfvars @@ -0,0 +1,13 @@ +project_id = "my-project" +region = "europe-west1" +name = "nlb-test" +backends = [{ + group = "foo" + failover = false +}] +forwarding_rules_config = { + "port-80" = { + ports = [80] + } +} + diff --git a/tests/modules/net_lb_ext/forwarding-rule.yaml b/tests/modules/net_lb_ext/forwarding-rule.yaml new file mode 100644 index 00000000..f60787d6 --- /dev/null +++ b/tests/modules/net_lb_ext/forwarding-rule.yaml @@ -0,0 +1,23 @@ +# 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: + google_compute_forwarding_rule.forwarding_rules["port-80"]: + all_ports: null + ports: + - '80' + +counts: + google_compute_forwarding_rule: 1 + google_compute_region_backend_service: 1 diff --git a/tests/modules/net_lb_ext/tftest.yaml b/tests/modules/net_lb_ext/tftest.yaml new file mode 100644 index 00000000..c219e478 --- /dev/null +++ b/tests/modules/net_lb_ext/tftest.yaml @@ -0,0 +1,20 @@ +# 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. + +module: modules/net-lb-ext + +tests: + defaults: + dual-stack: + forwarding-rule: