From 27f6e11e83be91043f453991014c1e4985da2ec8 Mon Sep 17 00:00:00 2001 From: The Magician Date: Wed, 27 Dec 2023 13:23:41 -0800 Subject: [PATCH] Add support of provisioned iops and throughput on boot disk. (#9649) (#16871) [upstream:b3eada0996063fbb3a6ade12770ea64eef87f5cc] Signed-off-by: Modular Magician --- .changelog/9649.txt | 3 ++ .../compute/resource_compute_instance.go | 40 ++++++++++++-- .../compute/resource_compute_instance_test.go | 54 +++++++++++++++++++ website/docs/r/compute_instance.html.markdown | 16 ++++++ 4 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 .changelog/9649.txt diff --git a/.changelog/9649.txt b/.changelog/9649.txt new file mode 100644 index 00000000000..5c4299d5461 --- /dev/null +++ b/.changelog/9649.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +compute: added `provisioned_iops`and `provisioned_throughput` fields under `boot_disk.initialize_params` to `google_compute_instance` resource +``` diff --git a/google/services/compute/resource_compute_instance.go b/google/services/compute/resource_compute_instance.go index 5f812288151..fb1cca67f3f 100644 --- a/google/services/compute/resource_compute_instance.go +++ b/google/services/compute/resource_compute_instance.go @@ -43,6 +43,8 @@ var ( "boot_disk.0.initialize_params.0.image", "boot_disk.0.initialize_params.0.labels", "boot_disk.0.initialize_params.0.resource_manager_tags", + "boot_disk.0.initialize_params.0.provisioned_iops", + "boot_disk.0.initialize_params.0.provisioned_throughput", } schedulingKeys = []string{ @@ -234,6 +236,26 @@ func ResourceComputeInstance() *schema.Resource { ForceNew: true, Description: `A map of resource manager tags. Resource manager tag keys and values have the same definition as resource manager tags. Keys must be in the format tagKeys/{tag_key_id}, and values are in the format tagValues/456. The field is ignored (both PUT & PATCH) when empty.`, }, + + "provisioned_iops": { + Type: schema.TypeInt, + Optional: true, + AtLeastOneOf: initializeParamsKeys, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(10000, 120000), + 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.`, + }, + + "provisioned_throughput": { + Type: schema.TypeInt, + Optional: true, + AtLeastOneOf: initializeParamsKeys, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IntBetween(1, 7124), + Description: `Indicates how much throughput to provision for the disk. This sets the number of throughput mb per second that the disk can handle. Values must be between 1 and 7,124.`, + }, }, }, }, @@ -2596,6 +2618,14 @@ func expandBootDisk(d *schema.ResourceData, config *transport_tpg.Config, projec disk.InitializeParams.DiskSizeGb = int64(v.(int)) } + if v, ok := d.GetOk("boot_disk.0.initialize_params.0.provisioned_iops"); ok { + disk.InitializeParams.ProvisionedIops = int64(v.(int)) + } + + if v, ok := d.GetOk("boot_disk.0.initialize_params.0.provisioned_throughput"); ok { + disk.InitializeParams.ProvisionedThroughput = int64(v.(int)) + } + if v, ok := d.GetOk("boot_disk.0.initialize_params.0.type"); ok { diskTypeName := v.(string) diskType, err := readDiskType(config, d, diskTypeName) @@ -2657,10 +2687,12 @@ func flattenBootDisk(d *schema.ResourceData, disk *compute.AttachedDisk, config "type": tpgresource.GetResourceNameFromSelfLink(diskDetails.Type), // If the config specifies a family name that doesn't match the image name, then // the diff won't be properly suppressed. See DiffSuppressFunc for this field. - "image": diskDetails.SourceImage, - "size": diskDetails.SizeGb, - "labels": diskDetails.Labels, - "resource_manager_tags": d.Get("boot_disk.0.initialize_params.0.resource_manager_tags"), + "image": diskDetails.SourceImage, + "size": diskDetails.SizeGb, + "labels": diskDetails.Labels, + "resource_manager_tags": d.Get("boot_disk.0.initialize_params.0.resource_manager_tags"), + "provisioned_iops": diskDetails.ProvisionedIops, + "provisioned_throughput": diskDetails.ProvisionedThroughput, }} } diff --git a/google/services/compute/resource_compute_instance_test.go b/google/services/compute/resource_compute_instance_test.go index 99635852d83..a58fb3d6162 100644 --- a/google/services/compute/resource_compute_instance_test.go +++ b/google/services/compute/resource_compute_instance_test.go @@ -1782,6 +1782,29 @@ func TestAccComputeInstanceConfidentialInstanceConfigMain(t *testing.T) { }) } +func TestAccComputeInstance_hyperdiskBootDisk_provisioned_iops_throughput(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "instance_name": fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10)), + "zone": "us-central1-a", + "provisioned_iops": 12000, + "provisioned_throughput": 200, + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceHyperDiskBootDiskProvisionedIopsThroughput(context), + }, + computeInstanceImportStep(context["zone"].(string), context["instance_name"].(string), []string{"allow_stopping_for_update"}), + }, + }) +} + func TestAccComputeInstance_enableDisplay(t *testing.T) { t.Parallel() @@ -6307,6 +6330,37 @@ resource "google_compute_instance" "foobar" { `, instance, enableConfidentialCompute) } +func testAccComputeInstanceHyperDiskBootDiskProvisionedIopsThroughput(context map[string]interface{}) string { + return acctest.Nprintf(` +data "google_compute_image" "my_image" { + family = "ubuntu-2204-lts" + project = "ubuntu-os-cloud" +} + +data "google_project" "project" {} + +resource "google_compute_instance" "foobar" { + name = "%{instance_name}" + machine_type = "h3-standard-88" + zone = "%{zone}" + + boot_disk { + initialize_params { + image = data.google_compute_image.my_image.self_link + provisioned_iops = %{provisioned_iops} + provisioned_throughput = %{provisioned_throughput} + type = "hyperdisk-balanced" + size = 100 + } + } + + network_interface { + network = "default" + } +} +`, context) +} + func testAccComputeInstance_enableDisplay(instance string) string { return fmt.Sprintf(` data "google_compute_image" "my_image" { diff --git a/website/docs/r/compute_instance.html.markdown b/website/docs/r/compute_instance.html.markdown index 35f71e01f70..afafbfd43e3 100644 --- a/website/docs/r/compute_instance.html.markdown +++ b/website/docs/r/compute_instance.html.markdown @@ -249,6 +249,22 @@ is desired, you will need to modify your state file manually using * `resource_manager_tags` - (Optional) A tag is a key-value pair that can be attached to a Google Cloud resource. You can use tags to conditionally allow or deny policies based on whether a resource has a specific tag. This value is not returned by the API. In Terraform, this value cannot be updated and changing it will recreate the resource. +* `provisioned_iops` - (Optional) 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). + Note: Updating currently is only supported for hyperdisk skus via disk update + api/gcloud without the need to delete and recreate the disk, hyperdisk allows + for an update of IOPS every 4 hours. To update your hyperdisk more frequently, + you'll need to manually delete and recreate it. + +* `provisioned_throughput` - (Optional) Indicates how much throughput to provision for the disk. + This sets the number of throughput mb per second that the disk can handle. + Values must be between 1 and 7,124. Note: Updating currently is only supported + for hyperdisk skus via disk update api/gcloud without the need to delete and + recreate the disk, hyperdisk allows for an update of throughput every 4 hours. + To update your hyperdisk more frequently, you'll need to manually delete and recreate it. + The `scratch_disk` block supports: * `interface` - (Required) The disk interface to use for attaching this disk; either SCSI or NVME.