diff --git a/.changelog/12481.txt b/.changelog/12481.txt
new file mode 100644
index 0000000000..3170ca8701
--- /dev/null
+++ b/.changelog/12481.txt
@@ -0,0 +1,3 @@
+```release-note:enhancement
+tpuv2: added `network_configs` and `network_config.queue_count` fields to `google_tpu_v2_vm` resource
+```
\ No newline at end of file
diff --git a/google-beta/services/tpuv2/resource_tpu_v2_vm.go b/google-beta/services/tpuv2/resource_tpu_v2_vm.go
index 4a0b893ce9..ea27b79675 100644
--- a/google-beta/services/tpuv2/resource_tpu_v2_vm.go
+++ b/google-beta/services/tpuv2/resource_tpu_v2_vm.go
@@ -235,9 +235,61 @@ false, the specified subnetwork or network should have Private Google Access ena
Optional: true,
ForceNew: true,
Description: `The name of the network for the TPU node. It must be a preexisting Google Compute Engine
-network. If both network and subnetwork are specified, the given subnetwork must belong
-to the given network. If network is not specified, it will be looked up from the
-subnetwork if one is provided, or otherwise use "default".`,
+network. If none is provided, "default" will be used.`,
+ },
+ "queue_count": {
+ Type: schema.TypeInt,
+ Optional: true,
+ ForceNew: true,
+ Description: `Specifies networking queue count for TPU VM instance's network interface.`,
+ },
+ "subnetwork": {
+ Type: schema.TypeString,
+ Computed: true,
+ Optional: true,
+ ForceNew: true,
+ Description: `The name of the subnetwork for the TPU node. It must be a preexisting Google Compute
+Engine subnetwork. If none is provided, "default" will be used.`,
+ },
+ },
+ },
+ ConflictsWith: []string{"network_configs"},
+ },
+ "network_configs": {
+ Type: schema.TypeList,
+ Optional: true,
+ ForceNew: true,
+ Description: `Repeated network configurations for the TPU node. This field is used to specify multiple
+network configs for the TPU node.`,
+ Elem: &schema.Resource{
+ Schema: map[string]*schema.Schema{
+ "can_ip_forward": {
+ Type: schema.TypeBool,
+ Optional: true,
+ ForceNew: true,
+ Description: `Allows the TPU node to send and receive packets with non-matching destination or source
+IPs. This is required if you plan to use the TPU workers to forward routes.`,
+ },
+ "enable_external_ips": {
+ Type: schema.TypeBool,
+ Optional: true,
+ ForceNew: true,
+ Description: `Indicates that external IP addresses would be associated with the TPU workers. If set to
+false, the specified subnetwork or network should have Private Google Access enabled.`,
+ },
+ "network": {
+ Type: schema.TypeString,
+ Computed: true,
+ Optional: true,
+ ForceNew: true,
+ Description: `The name of the network for the TPU node. It must be a preexisting Google Compute Engine
+network. If none is provided, "default" will be used.`,
+ },
+ "queue_count": {
+ Type: schema.TypeInt,
+ Optional: true,
+ ForceNew: true,
+ Description: `Specifies networking queue count for TPU VM instance's network interface.`,
},
"subnetwork": {
Type: schema.TypeString,
@@ -245,12 +297,11 @@ subnetwork if one is provided, or otherwise use "default".`,
Optional: true,
ForceNew: true,
Description: `The name of the subnetwork for the TPU node. It must be a preexisting Google Compute
-Engine subnetwork. If both network and subnetwork are specified, the given subnetwork
-must belong to the given network. If subnetwork is not specified, the subnetwork with the
-same name as the network will be used.`,
+Engine subnetwork. If none is provided, "default" will be used.`,
},
},
},
+ ConflictsWith: []string{"network_config"},
},
"scheduling_config": {
Type: schema.TypeList,
@@ -500,6 +551,12 @@ func resourceTpuV2VmCreate(d *schema.ResourceData, meta interface{}) error {
} else if v, ok := d.GetOkExists("network_config"); !tpgresource.IsEmptyValue(reflect.ValueOf(networkConfigProp)) && (ok || !reflect.DeepEqual(v, networkConfigProp)) {
obj["networkConfig"] = networkConfigProp
}
+ networkConfigsProp, err := expandTpuV2VmNetworkConfigs(d.Get("network_configs"), d, config)
+ if err != nil {
+ return err
+ } else if v, ok := d.GetOkExists("network_configs"); !tpgresource.IsEmptyValue(reflect.ValueOf(networkConfigsProp)) && (ok || !reflect.DeepEqual(v, networkConfigsProp)) {
+ obj["networkConfigs"] = networkConfigsProp
+ }
serviceAccountProp, err := expandTpuV2VmServiceAccount(d.Get("service_account"), d, config)
if err != nil {
return err
@@ -679,6 +736,9 @@ func resourceTpuV2VmRead(d *schema.ResourceData, meta interface{}) error {
if err := d.Set("network_config", flattenTpuV2VmNetworkConfig(res["networkConfig"], d, config)); err != nil {
return fmt.Errorf("Error reading Vm: %s", err)
}
+ if err := d.Set("network_configs", flattenTpuV2VmNetworkConfigs(res["networkConfigs"], d, config)); err != nil {
+ return fmt.Errorf("Error reading Vm: %s", err)
+ }
if err := d.Set("service_account", flattenTpuV2VmServiceAccount(res["serviceAccount"], d, config)); err != nil {
return fmt.Errorf("Error reading Vm: %s", err)
}
@@ -972,6 +1032,8 @@ func flattenTpuV2VmNetworkConfig(v interface{}, d *schema.ResourceData, config *
flattenTpuV2VmNetworkConfigEnableExternalIps(original["enableExternalIps"], d, config)
transformed["can_ip_forward"] =
flattenTpuV2VmNetworkConfigCanIpForward(original["canIpForward"], d, config)
+ transformed["queue_count"] =
+ flattenTpuV2VmNetworkConfigQueueCount(original["queueCount"], d, config)
return []interface{}{transformed}
}
func flattenTpuV2VmNetworkConfigNetwork(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
@@ -990,6 +1052,78 @@ func flattenTpuV2VmNetworkConfigCanIpForward(v interface{}, d *schema.ResourceDa
return v
}
+func flattenTpuV2VmNetworkConfigQueueCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ // Handles the string fixed64 format
+ if strVal, ok := v.(string); ok {
+ if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
+ return intVal
+ }
+ }
+
+ // number values are represented as float64
+ if floatVal, ok := v.(float64); ok {
+ intVal := int(floatVal)
+ return intVal
+ }
+
+ return v // let terraform core handle it otherwise
+}
+
+func flattenTpuV2VmNetworkConfigs(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ if v == nil {
+ return v
+ }
+ l := v.([]interface{})
+ transformed := make([]interface{}, 0, len(l))
+ for _, raw := range l {
+ original := raw.(map[string]interface{})
+ if len(original) < 1 {
+ // Do not include empty json objects coming back from the api
+ continue
+ }
+ transformed = append(transformed, map[string]interface{}{
+ "network": flattenTpuV2VmNetworkConfigsNetwork(original["network"], d, config),
+ "subnetwork": flattenTpuV2VmNetworkConfigsSubnetwork(original["subnetwork"], d, config),
+ "enable_external_ips": flattenTpuV2VmNetworkConfigsEnableExternalIps(original["enableExternalIps"], d, config),
+ "can_ip_forward": flattenTpuV2VmNetworkConfigsCanIpForward(original["canIpForward"], d, config),
+ "queue_count": flattenTpuV2VmNetworkConfigsQueueCount(original["queueCount"], d, config),
+ })
+ }
+ return transformed
+}
+func flattenTpuV2VmNetworkConfigsNetwork(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenTpuV2VmNetworkConfigsSubnetwork(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenTpuV2VmNetworkConfigsEnableExternalIps(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenTpuV2VmNetworkConfigsCanIpForward(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ return v
+}
+
+func flattenTpuV2VmNetworkConfigsQueueCount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
+ // Handles the string fixed64 format
+ if strVal, ok := v.(string); ok {
+ if intVal, err := tpgresource.StringToFixed64(strVal); err == nil {
+ return intVal
+ }
+ }
+
+ // number values are represented as float64
+ if floatVal, ok := v.(float64); ok {
+ intVal := int(floatVal)
+ return intVal
+ }
+
+ return v // let terraform core handle it otherwise
+}
+
func flattenTpuV2VmServiceAccount(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} {
if v == nil {
return nil
@@ -1321,6 +1455,13 @@ func expandTpuV2VmNetworkConfig(v interface{}, d tpgresource.TerraformResourceDa
transformed["canIpForward"] = transformedCanIpForward
}
+ transformedQueueCount, err := expandTpuV2VmNetworkConfigQueueCount(original["queue_count"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedQueueCount); val.IsValid() && !tpgresource.IsEmptyValue(val) {
+ transformed["queueCount"] = transformedQueueCount
+ }
+
return transformed, nil
}
@@ -1340,6 +1481,80 @@ func expandTpuV2VmNetworkConfigCanIpForward(v interface{}, d tpgresource.Terrafo
return v, nil
}
+func expandTpuV2VmNetworkConfigQueueCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandTpuV2VmNetworkConfigs(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+ l := v.([]interface{})
+ req := make([]interface{}, 0, len(l))
+ for _, raw := range l {
+ if raw == nil {
+ continue
+ }
+ original := raw.(map[string]interface{})
+ transformed := make(map[string]interface{})
+
+ transformedNetwork, err := expandTpuV2VmNetworkConfigsNetwork(original["network"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedNetwork); val.IsValid() && !tpgresource.IsEmptyValue(val) {
+ transformed["network"] = transformedNetwork
+ }
+
+ transformedSubnetwork, err := expandTpuV2VmNetworkConfigsSubnetwork(original["subnetwork"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedSubnetwork); val.IsValid() && !tpgresource.IsEmptyValue(val) {
+ transformed["subnetwork"] = transformedSubnetwork
+ }
+
+ transformedEnableExternalIps, err := expandTpuV2VmNetworkConfigsEnableExternalIps(original["enable_external_ips"], d, config)
+ if err != nil {
+ return nil, err
+ } else {
+ transformed["enableExternalIps"] = transformedEnableExternalIps
+ }
+
+ transformedCanIpForward, err := expandTpuV2VmNetworkConfigsCanIpForward(original["can_ip_forward"], d, config)
+ if err != nil {
+ return nil, err
+ } else {
+ transformed["canIpForward"] = transformedCanIpForward
+ }
+
+ transformedQueueCount, err := expandTpuV2VmNetworkConfigsQueueCount(original["queue_count"], d, config)
+ if err != nil {
+ return nil, err
+ } else if val := reflect.ValueOf(transformedQueueCount); val.IsValid() && !tpgresource.IsEmptyValue(val) {
+ transformed["queueCount"] = transformedQueueCount
+ }
+
+ req = append(req, transformed)
+ }
+ return req, nil
+}
+
+func expandTpuV2VmNetworkConfigsNetwork(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandTpuV2VmNetworkConfigsSubnetwork(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandTpuV2VmNetworkConfigsEnableExternalIps(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandTpuV2VmNetworkConfigsCanIpForward(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+ return v, nil
+}
+
+func expandTpuV2VmNetworkConfigsQueueCount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
+ return v, nil
+}
+
func expandTpuV2VmServiceAccount(v interface{}, d tpgresource.TerraformResourceData, config *transport_tpg.Config) (interface{}, error) {
l := v.([]interface{})
if len(l) == 0 || l[0] == nil {
diff --git a/google-beta/services/tpuv2/resource_tpu_v2_vm_generated_test.go b/google-beta/services/tpuv2/resource_tpu_v2_vm_generated_test.go
index 324187c4d3..12c1a3dd7e 100644
--- a/google-beta/services/tpuv2/resource_tpu_v2_vm_generated_test.go
+++ b/google-beta/services/tpuv2/resource_tpu_v2_vm_generated_test.go
@@ -134,6 +134,7 @@ resource "google_tpu_v2_vm" "tpu" {
enable_external_ips = true
network = google_compute_network.network.id
subnetwork = google_compute_subnetwork.subnet.id
+ queue_count = 32
}
scheduling_config {
diff --git a/website/docs/r/tpu_v2_vm.html.markdown b/website/docs/r/tpu_v2_vm.html.markdown
index a2a93e7b4b..3638f5cba0 100644
--- a/website/docs/r/tpu_v2_vm.html.markdown
+++ b/website/docs/r/tpu_v2_vm.html.markdown
@@ -90,6 +90,7 @@ resource "google_tpu_v2_vm" "tpu" {
enable_external_ips = true
network = google_compute_network.network.id
subnetwork = google_compute_subnetwork.subnet.id
+ queue_count = 32
}
scheduling_config {
@@ -206,6 +207,12 @@ The following arguments are supported:
Network configurations for the TPU node.
Structure is [documented below](#nested_network_config).
+* `network_configs` -
+ (Optional)
+ Repeated network configurations for the TPU node. This field is used to specify multiple
+ network configs for the TPU node.
+ Structure is [documented below](#nested_network_configs).
+
* `service_account` -
(Optional)
The Google Cloud Platform Service Account to be used by the TPU node VMs. If None is
@@ -260,16 +267,12 @@ The following arguments are supported:
* `network` -
(Optional)
The name of the network for the TPU node. It must be a preexisting Google Compute Engine
- network. If both network and subnetwork are specified, the given subnetwork must belong
- to the given network. If network is not specified, it will be looked up from the
- subnetwork if one is provided, or otherwise use "default".
+ network. If none is provided, "default" will be used.
* `subnetwork` -
(Optional)
The name of the subnetwork for the TPU node. It must be a preexisting Google Compute
- Engine subnetwork. If both network and subnetwork are specified, the given subnetwork
- must belong to the given network. If subnetwork is not specified, the subnetwork with the
- same name as the network will be used.
+ Engine subnetwork. If none is provided, "default" will be used.
* `enable_external_ips` -
(Optional)
@@ -281,6 +284,36 @@ The following arguments are supported:
Allows the TPU node to send and receive packets with non-matching destination or source
IPs. This is required if you plan to use the TPU workers to forward routes.
+* `queue_count` -
+ (Optional)
+ Specifies networking queue count for TPU VM instance's network interface.
+
+The `network_configs` block supports:
+
+* `network` -
+ (Optional)
+ The name of the network for the TPU node. It must be a preexisting Google Compute Engine
+ network. If none is provided, "default" will be used.
+
+* `subnetwork` -
+ (Optional)
+ The name of the subnetwork for the TPU node. It must be a preexisting Google Compute
+ Engine subnetwork. If none is provided, "default" will be used.
+
+* `enable_external_ips` -
+ (Optional)
+ Indicates that external IP addresses would be associated with the TPU workers. If set to
+ false, the specified subnetwork or network should have Private Google Access enabled.
+
+* `can_ip_forward` -
+ (Optional)
+ Allows the TPU node to send and receive packets with non-matching destination or source
+ IPs. This is required if you plan to use the TPU workers to forward routes.
+
+* `queue_count` -
+ (Optional)
+ Specifies networking queue count for TPU VM instance's network interface.
+
The `service_account` block supports:
* `email` -