Skip to content

Commit

Permalink
feat(module/lb_external): Add IPv6 support to the module (#39)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelrn authored Sep 13, 2024
1 parent bbd9e72 commit 39c023c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 10 deletions.
9 changes: 8 additions & 1 deletion modules/lb_external/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@
- Can only use the nic0 (the base interface) of an instance.
- Cannot serve as a next hop in a GCP custom routing table entry.

## Limitation

### Supported Module Version with Regards to the Changed Provider's Default Values

- Module versions `<=2.0.6` supports `terraform-provider-google` version `<6.0`. If you are using `terraform-provider-google` version `6.0` and above choose module version `2.0.7` and above. This limitation is related to the [change](https://github.com/hashicorp/terraform-provider-google/commit/267f964bd4f2d9b48e8771c2a8397de3f6655ef7) in the default value of `balancing_mode` introduced in the `terraform-provider-google` version `6.0`

## Reference
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
### Requirements
Expand Down Expand Up @@ -59,8 +65,9 @@ No modules.
| <a name="input_network_tier"></a> [network\_tier](#input\_network\_tier) | The networking tier used for configuring this address. If this field is not specified, it is assumed to be PREMIUM. Possible values are PREMIUM and STANDARD. | `string` | `"PREMIUM"` | no |
| <a name="input_project"></a> [project](#input\_project) | The project to deploy to. If unset the default provider project is used. | `string` | `""` | no |
| <a name="input_region"></a> [region](#input\_region) | GCP region to deploy to. If unset the default provider region is used. | `string` | `null` | no |
| <a name="input_rules"></a> [rules](#input\_rules) | Map of objects, the keys are names of the external forwarding rules, each of the objects has the following attributes:<br><br>- `port_range`: (Required) The port your service is listening on. Can be a number (80) or a range (8080-8089, or even 1-65535).<br>- `ip_address`: (Optional) A public IP address on which to listen, must be in the same region as the LB and must be IPv4. If empty, automatically generates a new non-ephemeral IP on a PREMIUM tier.<br>- `ip_protocol`: (Optional) The IP protocol for the frontend forwarding rule: TCP, UDP, ESP, ICMP, or L3\_DEFAULT. Default is TCP.<br>- `all_ports`: (Optional) Allows all ports to be forwarded to the Backend Service | `any` | n/a | yes |
| <a name="input_rules"></a> [rules](#input\_rules) | Map of objects, the keys are names of the external forwarding rules, each of the objects has the following attributes:<br><br>- `port_range` : (Required) The port your service is listening on. Can be a number (80) or a range (8080-8089, or even 1-65535).<br>- `ip_version` : (Optional) The IP version that will be used by this Load Balancer rule. Possible values are: IPV4 (default), IPV6.<br>- `ip_address` : (Optional) An existing public IP address on which to listen, must be in the same region as the LB. IP version must correspond `ip_version`. <br> In case of IPv6 address specify address with a netmask, for example: 2600:1900:4020:bd2:8000:1::/96.<br> If empty, a new non-ephemeral IP address is created on the PREMIUM tier.<br>- `ip_protocol`: (Optional) The IP protocol for the frontend forwarding rule: TCP, UDP, ESP, ICMP, or L3\_DEFAULT. Default is TCP.<br>- `all_ports` : (Optional) Allows all ports to be forwarded to the Backend Service. | `any` | n/a | yes |
| <a name="input_session_affinity"></a> [session\_affinity](#input\_session\_affinity) | Controls distribution of new connections (or fragmented UDP packets) from clients to the backends, can influence available connection tracking configurations.<br>Valid values are: NONE (default), CLIENT\_IP, CLIENT\_IP\_PROTO, CLIENT\_IP\_PORT\_PROTO (only available for backend service based rules). | `string` | `"NONE"` | no |
| <a name="input_subnetwork"></a> [subnetwork](#input\_subnetwork) | Subnetwork for an IPv6 address creation. Required only for IPv6 load balancer rules. | `string` | `null` | no |

### Outputs

Expand Down
24 changes: 18 additions & 6 deletions modules/lb_external/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@ locals {
resource "google_compute_address" "this" {
for_each = { for k, v in var.rules : k => v if !can(v.ip_address) }

name = each.key
address_type = "EXTERNAL"
region = var.region
project = var.project
name = each.key
address_type = "EXTERNAL"
region = var.region
project = var.project
ip_version = try(each.value.ip_version, null)
ipv6_endpoint_type = try(each.value.ip_version, "IPV4") == "IPV6" ? "NETLB" : null
subnetwork = try(each.value.ip_version, "IPV4") == "IPV6" ? var.subnetwork : null
}

# Create forwarding rule for each specified rule
Expand Down Expand Up @@ -47,8 +50,16 @@ resource "google_compute_forwarding_rule" "rule" {
# If false set value to the value of `port_range`. If `port_range` isn't specified, then set the value to `null`.
port_range = lookup(each.value, "ip_protocol", "TCP") == "L3_DEFAULT" ? null : lookup(each.value, "port_range", null)

ip_address = try(each.value.ip_address, google_compute_address.this[each.key].address)
ip_address = try(each.value.ip_address, try(each.value.ip_version, "IPV4") == "IPV4" ? (
google_compute_address.this[each.key].address
) : (
"${google_compute_address.this[each.key].address}/${google_compute_address.this[each.key].prefix_length}"
))
ip_protocol = lookup(each.value, "ip_protocol", "TCP")
# Provider recreates resource if `ip_version` changes.
# Use `null` as a default value to prevent existing LB re-creation when `ip_version` parameter is introduced.
ip_version = lookup(each.value, "ip_version", null)
subnetwork = lookup(each.value, "ip_version", "IPV4") == "IPV6" ? var.subnetwork : null
}

# Create `google_compute_target_pool` if required by `var.rules`
Expand Down Expand Up @@ -102,7 +113,8 @@ resource "google_compute_region_backend_service" "this" {
dynamic "backend" {
for_each = var.backend_instance_groups
content {
group = backend.value
group = backend.value
balancing_mode = "CONNECTION"
}
}

Expand Down
15 changes: 12 additions & 3 deletions modules/lb_external/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,23 @@ variable "rules" {
description = <<-EOF
Map of objects, the keys are names of the external forwarding rules, each of the objects has the following attributes:
- `port_range`: (Required) The port your service is listening on. Can be a number (80) or a range (8080-8089, or even 1-65535).
- `ip_address`: (Optional) A public IP address on which to listen, must be in the same region as the LB and must be IPv4. If empty, automatically generates a new non-ephemeral IP on a PREMIUM tier.
- `port_range` : (Required) The port your service is listening on. Can be a number (80) or a range (8080-8089, or even 1-65535).
- `ip_version` : (Optional) The IP version that will be used by this Load Balancer rule. Possible values are: IPV4 (default), IPV6.
- `ip_address` : (Optional) An existing public IP address on which to listen, must be in the same region as the LB. IP version must correspond `ip_version`.
In case of IPv6 address specify address with a netmask, for example: 2600:1900:4020:bd2:8000:1::/96.
If empty, a new non-ephemeral IP address is created on the PREMIUM tier.
- `ip_protocol`: (Optional) The IP protocol for the frontend forwarding rule: TCP, UDP, ESP, ICMP, or L3_DEFAULT. Default is TCP.
- `all_ports`: (Optional) Allows all ports to be forwarded to the Backend Service
- `all_ports` : (Optional) Allows all ports to be forwarded to the Backend Service.
EOF
}

variable "subnetwork" {
description = "Subnetwork for an IPv6 address creation. Required only for IPv6 load balancer rules."
type = string
default = null
}

variable "instances" {
description = "List of links to the instances. Expected to be empty when using an autoscaler, as the autoscaler inserts entries to the target pool dynamically. The nic0 of each instance gets the traffic. Even when this list is shifted or re-ordered, it doesn't re-create any resources and such modifications often proceed without any noticeable downtime."
type = list(string)
Expand Down

0 comments on commit 39c023c

Please sign in to comment.