diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb index 3d991d545028..1aa43d6df564 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template.go.erb @@ -169,6 +169,14 @@ func ResourceComputeInstanceTemplate() *schema.Resource { Description: `A set of key/value label pairs to assign to disks,`, }, + "provisioned_iops": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Computed: true, + Description: `Indicates how many IOPS to provision for the disk. This sets the number of I/O operations per second that the disk can handle. Values must be between 10,000 and 120,000. For more details, see the [Extreme persistent disk documentation](https://cloud.google.com/compute/docs/disks/extreme-persistent-disk).`, + }, + "source_image": { Type: schema.TypeString, Optional: true, @@ -1112,7 +1120,7 @@ func buildDisks(d *schema.ResourceData, config *transport_tpg.Config) ([]*comput } if v, ok := d.GetOk(prefix + ".source"); ok { disk.Source = v.(string) - conflicts := []string{"disk_size_gb", "disk_name", "disk_type", "source_image", "source_snapshot", "labels"} + conflicts := []string{"disk_size_gb", "disk_name", "disk_type", "provisioned_iops", "source_image", "source_snapshot", "labels"} for _, conflict := range conflicts { if _, ok := d.GetOk(prefix + "." + conflict); ok { return nil, fmt.Errorf("Cannot use `source` with any of the fields in %s", conflicts) @@ -1132,6 +1140,9 @@ func buildDisks(d *schema.ResourceData, config *transport_tpg.Config) ([]*comput if v, ok := d.GetOk(prefix + ".disk_type"); ok { disk.InitializeParams.DiskType = v.(string) } + if v, ok := d.GetOk(prefix + ".provisioned_iops"); ok { + disk.InitializeParams.ProvisionedIops = int64(v.(int)) + } disk.InitializeParams.Labels = tpgresource.ExpandStringMap(d, prefix+".labels") @@ -1337,6 +1348,7 @@ type diskCharacteristics struct { diskSizeGb string autoDelete bool sourceImage string + provisionedIops string } func diskCharacteristicsFromMap(m map[string]interface{}) diskCharacteristics { @@ -1365,6 +1377,13 @@ func diskCharacteristicsFromMap(m map[string]interface{}) diskCharacteristics { if v := m["source_image"]; v != nil { dc.sourceImage = v.(string) } + + if v := m["provisioned_iops"]; v != nil { + // Terraform and GCP return ints as different types (int vs int64), so just + // use strings to compare for simplicity. + dc.provisionedIops = fmt.Sprintf("%v", v) + } + return dc } @@ -1388,6 +1407,7 @@ func flattenDisk(disk *compute.AttachedDisk, configDisk map[string]any, defaultP diskMap["source_image"] = "" } diskMap["disk_type"] = disk.InitializeParams.DiskType + diskMap["provisioned_iops"] = disk.InitializeParams.ProvisionedIops diskMap["disk_name"] = disk.InitializeParams.DiskName diskMap["labels"] = disk.InitializeParams.Labels // The API does not return a disk size value for scratch disks. They are largely only one size, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template_test.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template_test.go.erb index 67a6b0dfdcba..3c9dc02c177f 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_instance_template_test.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_instance_template_test.go.erb @@ -339,6 +339,26 @@ func TestAccComputeInstanceTemplate_regionDisks(t *testing.T) { }) } +func TestAccComputeInstanceTemplate_diskIops(t *testing.T) { + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeInstanceTemplateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceTemplate_diskIops(acctest.RandString(t, 10)), + }, + { + ResourceName: "google_compute_instance_template.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccComputeInstanceTemplate_subnet_auto(t *testing.T) { t.Parallel() @@ -2233,6 +2253,35 @@ resource "google_compute_instance_template" "foobar" { `, suffix, suffix) } +func testAccComputeInstanceTemplate_diskIops(suffix string) string { + return fmt.Sprintf(` +data "google_compute_image" "my_image" { + family = "debian-11" + project = "debian-cloud" +} + +resource "google_compute_instance_template" "foobar" { + name = "tf-test-instance-template-%s" + machine_type = "e2-medium" + + disk { + source_image = data.google_compute_image.my_image.self_link + auto_delete = true + disk_size_gb = 100 + boot = true + provisioned_iops = 10000 + labels = { + foo = "bar" + } + } + + network_interface { + network = "default" + } +} +`, suffix) +} + func testAccComputeInstanceTemplate_subnet_auto(network, suffix string) string { return fmt.Sprintf(` data "google_compute_image" "my_image" { diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb index c495848b23ab..2050ede84d0c 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template.go.erb @@ -149,6 +149,14 @@ func ResourceComputeRegionInstanceTemplate() *schema.Resource { Description: `A set of key/value label pairs to assign to disks,`, }, + "provisioned_iops": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Computed: true, + Description: `Indicates how many IOPS to provision for the disk. This sets the number of I/O operations per second that the disk can handle. Values must be between 10,000 and 120,000. For more details, see the [Extreme persistent disk documentation](https://cloud.google.com/compute/docs/disks/extreme-persistent-disk).`, + }, + "source_image": { Type: schema.TypeString, Optional: true, diff --git a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template_test.go.erb b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template_test.go.erb index 7df7ad8bfe45..7535b0b5c97f 100644 --- a/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template_test.go.erb +++ b/mmv1/third_party/terraform/services/compute/resource_compute_region_instance_template_test.go.erb @@ -280,6 +280,26 @@ func TestAccComputeRegionInstanceTemplate_regionDisks(t *testing.T) { }) } +func TestAccComputeRegionInstanceTemplate_diskIops(t *testing.T) { + t.Parallel() + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeRegionInstanceTemplateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeRegionInstanceTemplate_diskIops(acctest.RandString(t, 10)), + }, + { + ResourceName: "google_compute_region_instance_template.foobar", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + func TestAccComputeRegionInstanceTemplate_subnet_auto(t *testing.T) { t.Parallel() @@ -2078,6 +2098,33 @@ resource "google_compute_region_instance_template" "foobar" { `, suffix, suffix) } +func testAccComputeRegionInstanceTemplate_diskIops(suffix string) string { + return fmt.Sprintf(` +data "google_compute_image" "my_image" { + family = "debian-11" + project = "debian-cloud" +} + +resource "google_compute_region_instance_template" "foobar" { + name = "tf-test-instance-template-%s" + machine_type = "e2-medium" + region = "us-central1" + + disk { + source_image = data.google_compute_image.my_image.self_link + auto_delete = true + disk_size_gb = 100 + boot = true + provisioned_iops = 10000 + } + + network_interface { + network = "default" + } +} +`, suffix) +} + func testAccComputeRegionInstanceTemplate_subnet_auto(network, suffix string) string { return fmt.Sprintf(` data "google_compute_image" "my_image" {