Skip to content

Commit e631969

Browse files
authored
Adding IPV6 & IDPF support (GoogleCloudPlatform#5066)
2 parents ab81e76 + 3188c8e commit e631969

9 files changed

Lines changed: 59 additions & 17 deletions

File tree

modules/compute/vm-instance/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ limitations under the License.
226226
| <a name="input_metadata"></a> [metadata](#input\_metadata) | Metadata, provided as a map | `map(string)` | `{}` | no |
227227
| <a name="input_min_cpu_platform"></a> [min\_cpu\_platform](#input\_min\_cpu\_platform) | The name of the minimum CPU platform that you want the instance to use. | `string` | `null` | no |
228228
| <a name="input_name_prefix"></a> [name\_prefix](#input\_name\_prefix) | An optional name for all VM and disk resources.<br/>If not supplied, `deployment_name` will be used.<br/>When `name_prefix` is supplied, and `add_deployment_name_before_prefix` is set,<br/>then resources are named by "<`deployment_name`>-<`name_prefix`>-<#>". | `string` | `null` | no |
229-
| <a name="input_network_interfaces"></a> [network\_interfaces](#input\_network\_interfaces) | A list of network interfaces. The options match that of the terraform<br/>network\_interface block of google\_compute\_instance. For descriptions of the<br/>subfields or more information see the documentation:<br/>https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#nested_network_interface<br/><br/>**\_NOTE:\_** If `network_interfaces` are set, `network_self_link` and<br/>`subnetwork_self_link` will be ignored, even if they are provided through<br/>the `use` field. `bandwidth_tier` and `disable_public_ips` also do not apply<br/>to network interfaces defined in this variable.<br/><br/>Subfields:<br/>network (string, required if subnetwork is not supplied)<br/>subnetwork (string, required if network is not supplied)<br/>subnetwork\_project (string, optional)<br/>network\_ip (string, optional)<br/>nic\_type (string, optional, choose from ["GVNIC", "VIRTIO\_NET", "MRDMA", "IRDMA"])<br/>stack\_type (string, optional, choose from ["IPV4\_ONLY", "IPV4\_IPV6"])<br/>queue\_count (number, optional)<br/>access\_config (object, optional)<br/>ipv6\_access\_config (object, optional)<br/>alias\_ip\_range (list(object), optional) | <pre>list(object({<br/> network = string,<br/> subnetwork = string,<br/> subnetwork_project = string,<br/> network_ip = string,<br/> nic_type = string,<br/> stack_type = string,<br/> queue_count = number,<br/> access_config = list(object({<br/> nat_ip = string,<br/> public_ptr_domain_name = string,<br/> network_tier = string<br/> })),<br/> ipv6_access_config = list(object({<br/> public_ptr_domain_name = string,<br/> network_tier = string<br/> })),<br/> alias_ip_range = list(object({<br/> ip_cidr_range = string,<br/> subnetwork_range_name = string<br/> }))<br/> }))</pre> | `[]` | no |
229+
| <a name="input_network_interfaces"></a> [network\_interfaces](#input\_network\_interfaces) | A list of network interfaces. The options match that of the terraform<br/>network\_interface block of google\_compute\_instance. For descriptions of the<br/>subfields or more information see the documentation:<br/>https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#nested_network_interface<br/><br/>**\_NOTE:\_** If `network_interfaces` are set, `network_self_link` and<br/>`subnetwork_self_link` will be ignored, even if they are provided through<br/>the `use` field. `bandwidth_tier` and `disable_public_ips` also do not apply<br/>to network interfaces defined in this variable.<br/><br/>Subfields:<br/>network (string, required if subnetwork is not supplied)<br/>subnetwork (string, required if network is not supplied)<br/>subnetwork\_project (string, optional)<br/>network\_ip (string, optional)<br/>nic\_type (string, optional, choose from ["GVNIC", "VIRTIO\_NET", "MRDMA", "IRDMA", "IDPF"])<br/>stack\_type (string, optional, choose from ["IPV4\_ONLY", "IPV4\_IPV6", "IPV6\_ONLY"])<br/>queue\_count (number, optional)<br/>access\_config (object, optional)<br/>ipv6\_access\_config (object, optional)<br/>alias\_ip\_range (list(object), optional) | <pre>list(object({<br/> network = string,<br/> subnetwork = string,<br/> subnetwork_project = string,<br/> network_ip = string,<br/> nic_type = string,<br/> stack_type = string,<br/> queue_count = number,<br/> access_config = list(object({<br/> nat_ip = string,<br/> public_ptr_domain_name = string,<br/> network_tier = string<br/> })),<br/> ipv6_access_config = list(object({<br/> public_ptr_domain_name = string,<br/> network_tier = string<br/> })),<br/> alias_ip_range = list(object({<br/> ip_cidr_range = string,<br/> subnetwork_range_name = string<br/> }))<br/> }))</pre> | `[]` | no |
230230
| <a name="input_network_self_link"></a> [network\_self\_link](#input\_network\_self\_link) | The self link of the network to attach the VM. Can use "default" for the default network. | `string` | `null` | no |
231231
| <a name="input_network_storage"></a> [network\_storage](#input\_network\_storage) | An array of network attached storage mounts to be configured. | <pre>list(object({<br/> server_ip = string,<br/> remote_mount = string,<br/> local_mount = string,<br/> fs_type = string,<br/> mount_options = string,<br/> client_install_runner = map(string)<br/> mount_runner = map(string)<br/> }))</pre> | `[]` | no |
232232
| <a name="input_on_host_maintenance"></a> [on\_host\_maintenance](#input\_on\_host\_maintenance) | Describes maintenance behavior for the instance. If left blank this will default to `MIGRATE` except for when `placement_policy`, spot provisioning, or GPUs require it to be `TERMINATE` | `string` | `null` | no |

modules/compute/vm-instance/variables.tf

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,8 @@ variable "network_interfaces" {
195195
subnetwork (string, required if network is not supplied)
196196
subnetwork_project (string, optional)
197197
network_ip (string, optional)
198-
nic_type (string, optional, choose from ["GVNIC", "VIRTIO_NET", "MRDMA", "IRDMA"])
199-
stack_type (string, optional, choose from ["IPV4_ONLY", "IPV4_IPV6"])
198+
nic_type (string, optional, choose from ["GVNIC", "VIRTIO_NET", "MRDMA", "IRDMA", "IDPF"])
199+
stack_type (string, optional, choose from ["IPV4_ONLY", "IPV4_IPV6", "IPV6_ONLY"])
200200
queue_count (number, optional)
201201
access_config (object, optional)
202202
ipv6_access_config (object, optional)
@@ -233,15 +233,15 @@ variable "network_interfaces" {
233233
}
234234
validation {
235235
condition = alltrue([
236-
for ni in var.network_interfaces : ni.nic_type == "GVNIC" || ni.nic_type == "VIRTIO_NET" || ni.nic_type == "MRDMA" || ni.nic_type == "IRDMA" || ni.nic_type == null
236+
for ni in var.network_interfaces : ni.nic_type == null || contains(["GVNIC", "VIRTIO_NET", "MRDMA", "IRDMA", "IDPF"], ni.nic_type)
237237
])
238-
error_message = "In the variable network_interfaces, field \"nic_type\" must be \"GVNIC\", \"VIRTIO_NET\", \"MRDMA\", \"IRDMA\", or null."
238+
error_message = "In the variable network_interfaces, field \"nic_type\" must be \"GVNIC\", \"VIRTIO_NET\", \"MRDMA\", \"IRDMA\", \"IDPF\" or null."
239239
}
240240
validation {
241241
condition = alltrue([
242-
for ni in var.network_interfaces : ni.stack_type == "IPV4_ONLY" || ni.stack_type == "IPV4_IPV6" || ni.stack_type == null
242+
for ni in var.network_interfaces : ni.stack_type == null || contains(["IPV4_ONLY", "IPV4_IPV6", "IPV6_ONLY"], ni.stack_type)
243243
])
244-
error_message = "In the variable network_interfaces, field \"stack_type\" must be either \"IPV4_ONLY\", \"IPV4_IPV6\" or null."
244+
error_message = "In the variable network_interfaces, field \"stack_type\" must be either \"IPV4_ONLY\", \"IPV4_IPV6\", \"IPV6_ONLY\" or null."
245245
}
246246
}
247247

modules/network/gpu-rdma-vpc/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,9 @@ limitations under the License.
9797
9898
## Providers
9999
100-
No providers.
100+
| Name | Version |
101+
|------|---------|
102+
| <a name="provider_terraform"></a> [terraform](#provider\_terraform) | n/a |
101103
102104
## Modules
103105
@@ -107,7 +109,9 @@ No providers.
107109
108110
## Resources
109111
110-
No resources.
112+
| Name | Type |
113+
|------|------|
114+
| [terraform_data.network_profile_validation](https://registry.terraform.io/providers/hashicorp/terraform/latest/docs/resources/data) | resource |
111115
112116
## Inputs
113117

modules/network/gpu-rdma-vpc/main.tf

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@
1717
locals {
1818
autoname = replace(var.deployment_name, "_", "-")
1919
network_name = var.network_name == null ? "${local.autoname}-net" : var.network_name
20-
subnet_prefix = var.subnetworks_template.name_prefix == null ? "${local.autoname}-subnet" : var.subnetworks_template.name_prefix
20+
subnet_prefix = var.subnetworks_template == null || var.subnetworks_template.name_prefix == null ? "${local.autoname}-subnet" : var.subnetworks_template.name_prefix
21+
is_roce_metal = var.network_profile != null ? can(regex("vpc-roce-metal", var.network_profile)) : false
2122

22-
new_bits = ceil(log(var.subnetworks_template.count, 2))
23-
template_subnetworks = [for i in range(var.subnetworks_template.count) :
23+
new_bits = local.is_roce_metal ? 0 : ceil(log(var.subnetworks_template.count, 2))
24+
/** RoCE metal profile doesn't allow creating a subnetwork, as the profile
25+
* automatically creates a predefined subnetwork for the MRDMA interfaces.
26+
* See: https://cloud.google.com/vpc/docs/network-profiles
27+
**/
28+
template_subnetworks = local.is_roce_metal ? [] : [for i in range(var.subnetworks_template.count) :
2429
{
2530
subnet_name = "${local.subnet_prefix}-${i}"
2631
subnet_region = try(var.subnetworks_template.region, var.region)
@@ -77,3 +82,16 @@ module "vpc" {
7782
firewall_rules = local.firewall_rules
7883
network_profile = var.network_profile
7984
}
85+
86+
resource "terraform_data" "network_profile_validation" {
87+
lifecycle {
88+
precondition {
89+
condition = (
90+
can(regex("vpc-roce-metal", var.network_profile)) ?
91+
var.subnetworks_template == null :
92+
var.subnetworks_template != null
93+
)
94+
error_message = "subnetworks_template must be null when using 'vpc-roce-metal' network profile and non-null for all other profiles."
95+
}
96+
}
97+
}

modules/network/gpu-rdma-vpc/outputs.tf

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ output "subnetwork_interfaces_gke" {
5555

5656
output "subnetwork_name_prefix" {
5757
description = "Prefix of the RDMA subnetwork names"
58-
value = var.subnetworks_template.name_prefix
58+
# This uses a conditional: if the variable is null, return null; otherwise, return the prefix.
59+
value = var.subnetworks_template != null ? var.subnetworks_template.name_prefix : null
5960
}

modules/network/gpu-rdma-vpc/variables.tf

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ variable "subnetworks_template" {
5050
ip_range (string, required, range of IPs for all subnets to share (CIDR format), default is 192.168.0.0/16)
5151
region (string, optional, region to deploy subnets to, defaults to vars.region)
5252
EOT
53-
nullable = false
53+
nullable = true
5454
type = object({
5555
count = number
5656
name_prefix = string
@@ -65,12 +65,15 @@ variable "subnetworks_template" {
6565
}
6666

6767
validation {
68-
condition = var.subnetworks_template.count > 0
69-
error_message = "Number of subnetworks must be greater than 0"
68+
# If template is provided, count must be > 0
69+
condition = var.subnetworks_template == null ? true : var.subnetworks_template.count > 0
70+
error_message = "Number of subnetworks must be greater than 0."
7071
}
7172

7273
validation {
73-
condition = can(cidrhost(var.subnetworks_template.ip_range, 0))
74+
# If the template is null, return true (pass).
75+
# Otherwise, check if the CIDR format is valid.
76+
condition = var.subnetworks_template == null ? true : can(cidrhost(var.subnetworks_template.ip_range, 0))
7477
error_message = "IP address range must be in CIDR format."
7578
}
7679
}

modules/network/vpc/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,11 @@ limitations under the License.
200200
| <a name="input_enable_iap_ssh_ingress"></a> [enable\_iap\_ssh\_ingress](#input\_enable\_iap\_ssh\_ingress) | Enable a firewall rule to allow SSH access using IAP tunnels | `bool` | `true` | no |
201201
| <a name="input_enable_iap_winrm_ingress"></a> [enable\_iap\_winrm\_ingress](#input\_enable\_iap\_winrm\_ingress) | Enable a firewall rule to allow Windows Remote Management (WinRM) access using IAP tunnels | `bool` | `false` | no |
202202
| <a name="input_enable_internal_traffic"></a> [enable\_internal\_traffic](#input\_enable\_internal\_traffic) | Enable a firewall rule to allow all internal TCP, UDP, and ICMP traffic within the network | `bool` | `true` | no |
203+
| <a name="input_enable_ipv6_ula"></a> [enable\_ipv6\_ula](#input\_enable\_ipv6\_ula) | Enable IPv6 ULA, this is a permanent change and cannot be undone! | `bool` | `false` | no |
203204
| <a name="input_extra_iap_ports"></a> [extra\_iap\_ports](#input\_extra\_iap\_ports) | A list of TCP ports for which to create firewall rules that enable IAP for TCP forwarding (use dedicated enable\_iap variables for standard ports) | `list(string)` | `[]` | no |
204205
| <a name="input_firewall_log_config"></a> [firewall\_log\_config](#input\_firewall\_log\_config) | Firewall log configuration for Toolkit firewall rules (var.enable\_iap\_ssh\_ingress and others) | `string` | `"DISABLE_LOGGING"` | no |
205206
| <a name="input_firewall_rules"></a> [firewall\_rules](#input\_firewall\_rules) | List of firewall rules | `any` | `[]` | no |
207+
| <a name="input_internal_ipv6_range"></a> [internal\_ipv6\_range](#input\_internal\_ipv6\_range) | When enabling IPv6 ULA, optionally specify a /48 from fd20::/20 (default null) | `string` | `null` | no |
206208
| <a name="input_ips_per_nat"></a> [ips\_per\_nat](#input\_ips\_per\_nat) | The number of IP addresses to allocate for each regional Cloud NAT (set to 0 to disable NAT). The number of NAT IPs depend on the port reservation allocated for each node and the number of ports that a single NAT IP can serve. Refer this documentation for more details: https://cloud.google.com/nat/docs/ports-and-addresses#port-reservation-examples | `number` | `2` | no |
207209
| <a name="input_labels"></a> [labels](#input\_labels) | Labels to add to network resources that support labels. Key-value pairs of strings. | `map(string)` | `{}` | no |
208210
| <a name="input_mtu"></a> [mtu](#input\_mtu) | The network MTU (default: 8896). Recommended values: 0 (use Compute Engine default), 1460 (default outside HPC environments), 1500 (Internet default), or 8896 (for Jumbo packets). Allowed are all values in the range 1300 to 8896, inclusively. | `number` | `8896` | no |

modules/network/vpc/main.tf

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ module "vpc" {
191191
secondary_ranges = length(local.secondary_ranges_map) > 0 ? local.secondary_ranges_map : var.secondary_ranges
192192
routing_mode = var.network_routing_mode
193193
mtu = var.mtu
194+
enable_ipv6_ula = var.enable_ipv6_ula
195+
internal_ipv6_range = var.internal_ipv6_range
194196
description = var.network_description
195197
shared_vpc_host = var.shared_vpc_host
196198
delete_default_internet_gateway_routes = var.delete_default_internet_gateway_routes

modules/network/vpc/variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,18 @@ variable "mtu" {
8282
default = 8896
8383
}
8484

85+
variable "enable_ipv6_ula" {
86+
description = "Enable IPv6 ULA, this is a permanent change and cannot be undone!"
87+
type = bool
88+
default = false
89+
}
90+
91+
variable "internal_ipv6_range" {
92+
description = "When enabling IPv6 ULA, optionally specify a /48 from fd20::/20 (default null)"
93+
type = string
94+
default = null
95+
}
96+
8597
variable "subnetworks" {
8698
description = <<-EOT
8799
List of subnetworks to create within the VPC. If left empty, it will be

0 commit comments

Comments
 (0)