diff --git a/blueprints/apigee/hybrid-gke/glb.tf b/blueprints/apigee/hybrid-gke/glb.tf
index 80ff2269c2..247b92b502 100644
--- a/blueprints/apigee/hybrid-gke/glb.tf
+++ b/blueprints/apigee/hybrid-gke/glb.tf
@@ -19,7 +19,9 @@ locals {
}
module "addresses" {
- source = "../../../modules/net-address"
- project_id = module.project.project_id
- global_addresses = [local.ingress_ip_name]
+ source = "../../../modules/net-address"
+ project_id = module.project.project_id
+ global_addresses = {
+ "${local.ingress_ip_name}" = {}
+ }
}
diff --git a/blueprints/gke/autopilot/glbs.tf b/blueprints/gke/autopilot/glbs.tf
index 39897c43d5..026411e011 100644
--- a/blueprints/gke/autopilot/glbs.tf
+++ b/blueprints/gke/autopilot/glbs.tf
@@ -19,7 +19,11 @@ locals {
}
module "addresses" {
- source = "../../../modules/net-address"
- project_id = module.project.project_id
- global_addresses = ["grafana", "locust", "app"]
+ source = "../../../modules/net-address"
+ project_id = module.project.project_id
+ global_addresses = {
+ app = {}
+ grafana = {}
+ locust = {}
+ }
}
diff --git a/blueprints/third-party-solutions/phpipam/glb.tf b/blueprints/third-party-solutions/phpipam/glb.tf
index 9016330eeb..2a9aa44989 100644
--- a/blueprints/third-party-solutions/phpipam/glb.tf
+++ b/blueprints/third-party-solutions/phpipam/glb.tf
@@ -21,10 +21,12 @@ locals {
# Reserved static IP for the Load Balancer
module "addresses" {
- source = "../../../modules/net-address"
- count = local.glb_create ? 1 : 0
- project_id = var.project_id
- global_addresses = ["phpipam"]
+ source = "../../../modules/net-address"
+ count = local.glb_create ? 1 : 0
+ project_id = var.project_id
+ global_addresses = {
+ phpipam = {}
+ }
}
# Global L7 HTTPS Load Balancer in front of Cloud Run
diff --git a/modules/net-address/README.md b/modules/net-address/README.md
index c99ca511ae..02eb6458e3 100644
--- a/modules/net-address/README.md
+++ b/modules/net-address/README.md
@@ -14,7 +14,10 @@ module "addresses" {
one = { region = "europe-west1" }
two = { region = "europe-west2" }
}
- global_addresses = ["app-1", "app-2"]
+ global_addresses = {
+ app-1 = {}
+ app-2 = {}
+ }
}
# tftest modules=1 resources=4 inventory=external.yaml
```
@@ -41,6 +44,40 @@ module "addresses" {
# tftest modules=1 resources=2 inventory=internal.yaml
```
+### IPv6 addresses
+
+You can reserve both external and internal IPv6 addresses.
+
+```hcl
+module "addresses" {
+ source = "./fabric/modules/net-address"
+ project_id = var.project_id
+ external_addresses = {
+ nlb = {
+ region = var.region
+ subnetwork = var.subnet.self_link
+ ipv6 = {
+ endpoint_type = "NETLB"
+ }
+ }
+ }
+ internal_addresses = {
+ ilb = {
+ ipv6 = {}
+ purpose = "SHARED_LOADBALANCER_VIP"
+ region = var.region
+ subnetwork = var.subnet.self_link
+ }
+ vm = {
+ ipv6 = {}
+ region = var.region
+ subnetwork = var.subnet.self_link
+ }
+ }
+}
+# tftest modules=1 resources=3 inventory=ipv6.yaml
+```
+
### PSA addresses
```hcl
@@ -106,13 +143,13 @@ module "addresses" {
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
-| [project_id](variables.tf#L68) | Project where the addresses will be created. | string
| ✓ | |
-| [external_addresses](variables.tf#L17) | Map of external addresses, keyed by name. | map(object({…}))
| | {}
|
-| [global_addresses](variables.tf#L28) | List of global addresses to create. | list(string)
| | []
|
-| [internal_addresses](variables.tf#L34) | Map of internal addresses to create, keyed by name. | map(object({…}))
| | {}
|
-| [ipsec_interconnect_addresses](variables.tf#L49) | Map of internal addresses used for HPA VPN over Cloud Interconnect. | map(object({…}))
| | {}
|
-| [psa_addresses](variables.tf#L73) | Map of internal addresses used for Private Service Access. | map(object({…}))
| | {}
|
-| [psc_addresses](variables.tf#L86) | Map of internal addresses used for Private Service Connect. | map(object({…}))
| | {}
|
+| [project_id](variables.tf#L83) | Project where the addresses will be created. | string
| ✓ | |
+| [external_addresses](variables.tf#L17) | Map of external addresses, keyed by name. | map(object({…}))
| | {}
|
+| [global_addresses](variables.tf#L38) | List of global addresses to create. | map(object({…}))
| | {}
|
+| [internal_addresses](variables.tf#L48) | Map of internal addresses to create, keyed by name. | map(object({…}))
| | {}
|
+| [ipsec_interconnect_addresses](variables.tf#L64) | Map of internal addresses used for HPA VPN over Cloud Interconnect. | map(object({…}))
| | {}
|
+| [psa_addresses](variables.tf#L88) | Map of internal addresses used for Private Service Access. | map(object({…}))
| | {}
|
+| [psc_addresses](variables.tf#L101) | Map of internal addresses used for Private Service Connect. | map(object({…}))
| | {}
|
## Outputs
diff --git a/modules/net-address/main.tf b/modules/net-address/main.tf
index f80cab291c..9f9d52303a 100644
--- a/modules/net-address/main.tf
+++ b/modules/net-address/main.tf
@@ -15,20 +15,24 @@
*/
resource "google_compute_global_address" "global" {
- for_each = toset(var.global_addresses)
- project = var.project_id
- name = each.value
+ for_each = var.global_addresses
+ project = var.project_id
+ name = coalesce(each.value.name, each.key)
+ description = each.value.description
+ ip_version = each.value.ipv6 != null ? "IPV6" : "IPV4"
}
resource "google_compute_address" "external" {
- provider = google-beta
- for_each = var.external_addresses
- project = var.project_id
- name = coalesce(each.value.name, each.key)
- description = each.value.description
- address_type = "EXTERNAL"
- region = each.value.region
- labels = each.value.labels
+ provider = google-beta
+ for_each = var.external_addresses
+ project = var.project_id
+ name = coalesce(each.value.name, each.key)
+ description = each.value.description
+ address_type = "EXTERNAL"
+ ip_version = each.value.ipv6 != null ? "IPV6" : "IPV4"
+ ipv6_endpoint_type = try(each.value.ipv6.endpoint_type, null)
+ region = each.value.region
+ labels = each.value.labels
}
resource "google_compute_address" "internal" {
@@ -41,6 +45,7 @@ resource "google_compute_address" "internal" {
region = each.value.region
subnetwork = each.value.subnetwork
address = each.value.address
+ ip_version = each.value.ipv6 != null ? "IPV6" : "IPV4"
network_tier = each.value.tier
purpose = each.value.purpose
labels = coalesce(each.value.labels, {})
diff --git a/modules/net-address/variables.tf b/modules/net-address/variables.tf
index 9f7c5c70d3..5a6fd683b1 100644
--- a/modules/net-address/variables.tf
+++ b/modules/net-address/variables.tf
@@ -19,16 +19,30 @@ variable "external_addresses" {
type = map(object({
region = string
description = optional(string, "Terraform managed.")
- labels = optional(map(string), {})
- name = optional(string)
+ ipv6 = optional(object({
+ endpoint_type = string
+ }))
+ labels = optional(map(string), {})
+ name = optional(string)
}))
default = {}
+ validation {
+ condition = (
+ try(var.external_addresses.ipv6, null) == null
+ || can(regex("^(NETLB|VM)$", try(var.external_addresses.ipv6.endpoint_type, null)))
+ )
+ error_message = "IPv6 endpoint type must be NETLB, VM."
+ }
}
variable "global_addresses" {
description = "List of global addresses to create."
- type = list(string)
- default = []
+ type = map(object({
+ description = optional(string, "Terraform managed.")
+ ipv6 = optional(map(string)) # To be left empty for ipv6
+ name = optional(string)
+ }))
+ default = {}
}
variable "internal_addresses" {
@@ -38,6 +52,7 @@ variable "internal_addresses" {
subnetwork = string
address = optional(string)
description = optional(string, "Terraform managed.")
+ ipv6 = optional(map(string)) # To be left empty for ipv6
labels = optional(map(string))
name = optional(string)
purpose = optional(string)
diff --git a/modules/net-lb-app-ext/README.md b/modules/net-lb-app-ext/README.md
index f404f105e1..72b1e48ff8 100644
--- a/modules/net-lb-app-ext/README.md
+++ b/modules/net-lb-app-ext/README.md
@@ -129,9 +129,11 @@ Redirect is implemented via an additional HTTP load balancer with a custom URL m
```hcl
module "addresses" {
- source = "./fabric/modules/net-address"
- project_id = "myprj"
- global_addresses = ["glb-test-0"]
+ source = "./fabric/modules/net-address"
+ project_id = "myprj"
+ global_addresses = {
+ "glb-test-0" = {}
+ }
}
module "glb-test-0-redirect" {
diff --git a/tests/modules/net_address/examples/ipv6.yaml b/tests/modules/net_address/examples/ipv6.yaml
new file mode 100644
index 0000000000..306e39c676
--- /dev/null
+++ b/tests/modules/net_address/examples/ipv6.yaml
@@ -0,0 +1,44 @@
+# 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["nlb"]:
+ address_type: EXTERNAL
+ ip_version: IPV6
+ ipv6_endpoint_type: NETLB
+ name: nlb
+ project: project-id
+ region: region
+ module.addresses.google_compute_address.internal["ilb"]:
+ address_type: INTERNAL
+ ip_version: IPV6
+ labels: null
+ name: ilb
+ network: null
+ project: project-id
+ purpose: SHARED_LOADBALANCER_VIP
+ region: region
+ subnetwork: subnet_self_link
+ module.addresses.google_compute_address.internal["vm"]:
+ address_type: INTERNAL
+ ip_version: IPV6
+ labels: null
+ name: vm
+ network: null
+ project: project-id
+ region: region
+ subnetwork: subnet_self_link
+
+counts:
+ google_compute_address: 3