From 3aee5dc054544a34c4fe61a1150c7034cead3dd7 Mon Sep 17 00:00:00 2001 From: Pavel Raunou Date: Wed, 11 Sep 2024 14:43:24 +0200 Subject: [PATCH] Adding IPv6 support to vmseries module --- modules/vmseries/README.md | 3 ++- modules/vmseries/main.tf | 34 ++++++++++++++++++++++++++++++++++ modules/vmseries/variables.tf | 20 ++++++++++++-------- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/modules/vmseries/README.md b/modules/vmseries/README.md index 30e160b..8376807 100644 --- a/modules/vmseries/README.md +++ b/modules/vmseries/README.md @@ -33,6 +33,7 @@ No modules. |------|------| | [google_compute_address.private](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_address) | resource | | [google_compute_address.public](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_address) | resource | +| [google_compute_address.public_v6](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_address) | resource | | [google_compute_instance.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance) | resource | | [google_compute_instance_group.this](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance_group) | resource | | [null_resource.dependency_getter](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource | @@ -56,7 +57,7 @@ No modules. | [min\_cpu\_platform](#input\_min\_cpu\_platform) | Minimum CPU platform for the compute instance. Up to date version can be found [here](https://cloud.google.com/compute/docs/instances/specify-min-cpu-platform). | `string` | `"Intel Cascade Lake"` | no | | [name](#input\_name) | Name of the VM-Series instance. | `string` | n/a | yes | | [named\_ports](#input\_named\_ports) | The list of named ports to create in the instance group:
named_ports = [
{
name = "http"
port = "80"
},
{
name = "app42"
port = "4242"
},
]
The name identifies the backend port to receive the traffic from the global load balancers.
Practically, tcp port 80 named "http" works even when not defined here, but it's not a documented provider's behavior. | `list` | `[]` | no | -| [network\_interfaces](#input\_network\_interfaces) | List of the network interface specifications.
Available options:
- `subnetwork` - (Required\|string) Self-link of a subnetwork to create interface in.
- `private_ip_name` - (Optional\|string) Name for a private address to reserve.
- `private_ip` - (Optional\|string) Private address to reserve.
- `create_public_ip` - (Optional\|boolean) Whether to reserve public IP for the interface. Ignored if `public_ip` is provided. Defaults to 'false'.
- `public_ip_name` - (Optional\|string) Name for a public address to reserve.
- `public_ip` - (Optional\|string) Existing public IP to use.
- `public_ptr_domain_name` - (Optional\|string) Existing public PTR name to use.
- `alias_ip_ranges` - (Optional\|list) List of objects that define additional IP ranges for an interface, as specified [here](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#ip_cidr_range) | `list(any)` | n/a | yes | +| [network\_interfaces](#input\_network\_interfaces) | List of the network interface specifications.
Available options:
- `subnetwork` - (Required\|string) Self-link of a subnetwork to create interface in.
- `private_ip_name` - (Optional\|string) Name for a private IPv4 address to reserve.
- `private_ip` - (Optional\|string) Private IPv4 address to reserve.
- `create_public_ip` - (Optional\|boolean) Whether to reserve public IPv4 address for the interface. Ignored if `public_ip` is provided. Defaults to 'false'.
- `public_ip_name` - (Optional\|string) Name for a public IPv4 address to reserve.
- `public_ip` - (Optional\|string) Existing public IPv4 address to use.
- `public_ptr_domain_name` - (Optional\|string) Existing public IPv4 address PTR name to use.
- `alias_ip_ranges` - (Optional\|list) List of objects that define additional IP ranges for an interface, as specified [here](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#ip_cidr_range)
- `create_public_ipv6` - (Optional\|boolean) Whether to reserve public IPv6 address for the interface. Ignored if `public_ipv6` is provided. Defaults to 'false'.
- `public_ipv6_name` - (Optional\|string) Name for a public IPv6 address to reserve.
- `public_ipv6` - (Optional\|string) Existing public IPv6 address to use.
- `public_ipv6_ptr_domain_name` - (Optional\|string) Existing public IPv6 address PTR name to use. | `list(any)` | n/a | yes | | [project](#input\_project) | n/a | `string` | `null` | no | | [resource\_policies](#input\_resource\_policies) | n/a | `list(string)` | `[]` | no | | [scopes](#input\_scopes) | n/a | `list(string)` |
[
"https://www.googleapis.com/auth/compute.readonly",
"https://www.googleapis.com/auth/cloud.useraccounts.readonly",
"https://www.googleapis.com/auth/devstorage.read_only",
"https://www.googleapis.com/auth/logging.write",
"https://www.googleapis.com/auth/monitoring.write"
]
| no | diff --git a/modules/vmseries/main.tf b/modules/vmseries/main.tf index a0dffe5..277cbe4 100644 --- a/modules/vmseries/main.tf +++ b/modules/vmseries/main.tf @@ -9,6 +9,17 @@ locals { } if try(v.public_ip, null) != null || local.create_public_ip[k] } + create_public_ipv6 = { + for k, v in var.network_interfaces : k => try(v.create_public_ipv6, false) + } + ipv6_access_configs = { + for k, v in var.network_interfaces : k => { + external_ipv6 = try(v.public_ipv6, null) != null ? v.public_ipv6 : local.create_public_ipv6[k] + external_ipv6_prefix_length = try(v.public_ipv6, null) != null ? try(v.public_ipv6_prefix_length, null) : google_compute_address.public_v6[k].prefix_length + public_ptr_domain_name = try(v.public_ipv6_ptr_domain_name, null) + } + if try(v.public_ipv6, null) != null || local.create_public_ipv6[k] + } } data "google_compute_image" "vmseries" { @@ -50,6 +61,18 @@ resource "google_compute_address" "public" { region = data.google_compute_subnetwork.this[each.key].region } +resource "google_compute_address" "public_v6" { + for_each = { for k, v in var.network_interfaces : k => v if local.create_public_ipv6[k] && try(v.public_ipv6, null) == null } + + name = try(each.value.public_ipv6_name, "${var.name}-${each.key}-public-v6") + address_type = "EXTERNAL" + ip_version = "IPV6" + ipv6_endpoint_type = "VM" + subnetwork = each.value.subnetwork + project = var.project + region = data.google_compute_subnetwork.this[each.key].region +} + resource "google_compute_instance" "this" { name = var.name @@ -82,6 +105,7 @@ resource "google_compute_instance" "this" { for_each = var.network_interfaces content { + stack_type = try(network_interface.value.stack_type, "IPV4_ONLY") network_ip = google_compute_address.private[network_interface.key].address subnetwork = network_interface.value.subnetwork @@ -100,6 +124,16 @@ resource "google_compute_instance" "this" { subnetwork_range_name = try(alias_ip_range.value.subnetwork_range_name, null) } } + + dynamic "ipv6_access_config" { + for_each = try(local.ipv6_access_configs[network_interface.key] != null, false) ? ["one"] : [] + content { + external_ipv6 = try(local.ipv6_access_configs[network_interface.key].external_ipv6, null) + external_ipv6_prefix_length = try(local.ipv6_access_configs[network_interface.key].external_ipv6_prefix_length, null) + network_tier = "PREMIUM" + public_ptr_domain_name = try(local.ipv6_access_configs[network_interface.key].public_ptr_domain_name, null) + } + } } } diff --git a/modules/vmseries/variables.tf b/modules/vmseries/variables.tf index 104f466..8d35caf 100644 --- a/modules/vmseries/variables.tf +++ b/modules/vmseries/variables.tf @@ -17,14 +17,18 @@ variable "network_interfaces" { description = <<-EOF List of the network interface specifications. Available options: - - `subnetwork` - (Required|string) Self-link of a subnetwork to create interface in. - - `private_ip_name` - (Optional|string) Name for a private address to reserve. - - `private_ip` - (Optional|string) Private address to reserve. - - `create_public_ip` - (Optional|boolean) Whether to reserve public IP for the interface. Ignored if `public_ip` is provided. Defaults to 'false'. - - `public_ip_name` - (Optional|string) Name for a public address to reserve. - - `public_ip` - (Optional|string) Existing public IP to use. - - `public_ptr_domain_name` - (Optional|string) Existing public PTR name to use. - - `alias_ip_ranges` - (Optional|list) List of objects that define additional IP ranges for an interface, as specified [here](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#ip_cidr_range) + - `subnetwork` - (Required|string) Self-link of a subnetwork to create interface in. + - `private_ip_name` - (Optional|string) Name for a private IPv4 address to reserve. + - `private_ip` - (Optional|string) Private IPv4 address to reserve. + - `create_public_ip` - (Optional|boolean) Whether to reserve public IPv4 address for the interface. Ignored if `public_ip` is provided. Defaults to 'false'. + - `public_ip_name` - (Optional|string) Name for a public IPv4 address to reserve. + - `public_ip` - (Optional|string) Existing public IPv4 address to use. + - `public_ptr_domain_name` - (Optional|string) Existing public IPv4 address PTR name to use. + - `alias_ip_ranges` - (Optional|list) List of objects that define additional IP ranges for an interface, as specified [here](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#ip_cidr_range) + - `create_public_ipv6` - (Optional|boolean) Whether to reserve public IPv6 address for the interface. Ignored if `public_ipv6` is provided. Defaults to 'false'. + - `public_ipv6_name` - (Optional|string) Name for a public IPv6 address to reserve. + - `public_ipv6` - (Optional|string) Existing public IPv6 address to use. + - `public_ipv6_ptr_domain_name` - (Optional|string) Existing public IPv6 address PTR name to use. EOF type = list(any) }