diff --git a/.changelog/4326.txt b/.changelog/4326.txt new file mode 100644 index 00000000000..2772bec797a --- /dev/null +++ b/.changelog/4326.txt @@ -0,0 +1,3 @@ +```release-note:enhancement +compute: promoted `confidential_instance_config` field in `google_compute_instance` and `google_compute_instance_template` to GA +``` diff --git a/google/compute_instance_helpers.go b/google/compute_instance_helpers.go index d68d0aefb3a..67fdc709177 100644 --- a/google/compute_instance_helpers.go +++ b/google/compute_instance_helpers.go @@ -320,6 +320,28 @@ func expandShieldedVmConfigs(d TerraformResourceData) *computeBeta.ShieldedInsta } } +func expandConfidentialInstanceConfig(d TerraformResourceData) *computeBeta.ConfidentialInstanceConfig { + if _, ok := d.GetOk("confidential_instance_config"); !ok { + return nil + } + + prefix := "confidential_instance_config.0" + return &computeBeta.ConfidentialInstanceConfig{ + EnableConfidentialCompute: d.Get(prefix + ".enable_confidential_compute").(bool), + ForceSendFields: []string{"EnableSecureBoot"}, + } +} + +func flattenConfidentialInstanceConfig(ConfidentialInstanceConfig *computeBeta.ConfidentialInstanceConfig) []map[string]bool { + if ConfidentialInstanceConfig == nil { + return nil + } + + return []map[string]bool{{ + "enable_confidential_compute": ConfidentialInstanceConfig.EnableConfidentialCompute, + }} +} + func flattenShieldedVmConfig(shieldedVmConfig *computeBeta.ShieldedInstanceConfig) []map[string]bool { if shieldedVmConfig == nil { return nil diff --git a/google/resource_compute_instance.go b/google/resource_compute_instance.go index dca7472ba3f..a5f82879dd9 100644 --- a/google/resource_compute_instance.go +++ b/google/resource_compute_instance.go @@ -629,6 +629,23 @@ func resourceComputeInstance() *schema.Resource { }, }, }, + "confidential_instance_config": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ForceNew: true, + Computed: true, + Description: `The Confidential VM config being used by the instance. on_host_maintenance has to be set to TERMINATE or this will fail to create.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enable_confidential_compute": { + Type: schema.TypeBool, + Required: true, + Description: `Defines whether the instance should have confidential compute enabled.`, + }, + }, + }, + }, "desired_status": { Type: schema.TypeString, Optional: true, @@ -827,25 +844,26 @@ func expandComputeInstance(project string, d *schema.ResourceData, config *Confi // Create the instance information return &computeBeta.Instance{ - CanIpForward: d.Get("can_ip_forward").(bool), - Description: d.Get("description").(string), - Disks: disks, - MachineType: machineTypeUrl, - Metadata: metadata, - Name: d.Get("name").(string), - NetworkInterfaces: networkInterfaces, - Tags: resourceInstanceTags(d), - Labels: expandLabels(d), - ServiceAccounts: expandServiceAccounts(d.Get("service_account").([]interface{})), - GuestAccelerators: accels, - MinCpuPlatform: d.Get("min_cpu_platform").(string), - Scheduling: scheduling, - DeletionProtection: d.Get("deletion_protection").(bool), - Hostname: d.Get("hostname").(string), - ForceSendFields: []string{"CanIpForward", "DeletionProtection"}, - ShieldedInstanceConfig: expandShieldedVmConfigs(d), - DisplayDevice: expandDisplayDevice(d), - ResourcePolicies: convertStringArr(d.Get("resource_policies").([]interface{})), + CanIpForward: d.Get("can_ip_forward").(bool), + Description: d.Get("description").(string), + Disks: disks, + MachineType: machineTypeUrl, + Metadata: metadata, + Name: d.Get("name").(string), + NetworkInterfaces: networkInterfaces, + Tags: resourceInstanceTags(d), + Labels: expandLabels(d), + ServiceAccounts: expandServiceAccounts(d.Get("service_account").([]interface{})), + GuestAccelerators: accels, + MinCpuPlatform: d.Get("min_cpu_platform").(string), + Scheduling: scheduling, + DeletionProtection: d.Get("deletion_protection").(bool), + Hostname: d.Get("hostname").(string), + ForceSendFields: []string{"CanIpForward", "DeletionProtection"}, + ConfidentialInstanceConfig: expandConfidentialInstanceConfig(d), + ShieldedInstanceConfig: expandShieldedVmConfigs(d), + DisplayDevice: expandDisplayDevice(d), + ResourcePolicies: convertStringArr(d.Get("resource_policies").([]interface{})), }, nil } @@ -1196,6 +1214,9 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error if err := d.Set("current_status", instance.Status); err != nil { return fmt.Errorf("Error setting current_status: %s", err) } + if err := d.Set("confidential_instance_config", flattenConfidentialInstanceConfig(instance.ConfidentialInstanceConfig)); err != nil { + return fmt.Errorf("Error setting confidential_instance_config: %s", err) + } if d.Get("desired_status") != "" { if err := d.Set("desired_status", instance.Status); err != nil { return fmt.Errorf("Error setting desired_status: %s", err) diff --git a/google/resource_compute_instance_template.go b/google/resource_compute_instance_template.go index 82f1ce30ef4..e2c0886f5a7 100644 --- a/google/resource_compute_instance_template.go +++ b/google/resource_compute_instance_template.go @@ -518,6 +518,23 @@ func resourceComputeInstanceTemplate() *schema.Resource { }, }, }, + "confidential_instance_config": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + ForceNew: true, + Computed: true, + Description: `The Confidential VM config being used by the instance. on_host_maintenance has to be set to TERMINATE or this will fail to create.`, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "enable_confidential_compute": { + Type: schema.TypeBool, + Required: true, + Description: `Defines whether the instance should have confidential compute enabled.`, + }, + }, + }, + }, "guest_accelerator": { Type: schema.TypeList, Optional: true, @@ -824,19 +841,20 @@ func resourceComputeInstanceTemplateCreate(d *schema.ResourceData, meta interfac } instanceProperties := &computeBeta.InstanceProperties{ - CanIpForward: d.Get("can_ip_forward").(bool), - Description: d.Get("instance_description").(string), - GuestAccelerators: expandInstanceTemplateGuestAccelerators(d, config), - MachineType: d.Get("machine_type").(string), - MinCpuPlatform: d.Get("min_cpu_platform").(string), - Disks: disks, - Metadata: metadata, - NetworkInterfaces: networks, - Scheduling: scheduling, - ServiceAccounts: expandServiceAccounts(d.Get("service_account").([]interface{})), - Tags: resourceInstanceTags(d), - ShieldedInstanceConfig: expandShieldedVmConfigs(d), - DisplayDevice: expandDisplayDevice(d), + CanIpForward: d.Get("can_ip_forward").(bool), + Description: d.Get("instance_description").(string), + GuestAccelerators: expandInstanceTemplateGuestAccelerators(d, config), + MachineType: d.Get("machine_type").(string), + MinCpuPlatform: d.Get("min_cpu_platform").(string), + Disks: disks, + Metadata: metadata, + NetworkInterfaces: networks, + Scheduling: scheduling, + ServiceAccounts: expandServiceAccounts(d.Get("service_account").([]interface{})), + Tags: resourceInstanceTags(d), + ConfidentialInstanceConfig: expandConfidentialInstanceConfig(d), + ShieldedInstanceConfig: expandShieldedVmConfigs(d), + DisplayDevice: expandDisplayDevice(d), } if _, ok := d.GetOk("labels"); ok { @@ -1219,6 +1237,11 @@ func resourceComputeInstanceTemplateRead(d *schema.ResourceData, meta interface{ } } + if instanceTemplate.Properties.ConfidentialInstanceConfig != nil { + if err = d.Set("confidential_instance_config", flattenConfidentialInstanceConfig(instanceTemplate.Properties.ConfidentialInstanceConfig)); err != nil { + return fmt.Errorf("Error setting confidential_instance_config: %s", err) + } + } if instanceTemplate.Properties.DisplayDevice != nil { if err = d.Set("enable_display", flattenEnableDisplay(instanceTemplate.Properties.DisplayDevice)); err != nil { return fmt.Errorf("Error setting enable_display: %s", err) diff --git a/google/resource_compute_instance_template_test.go b/google/resource_compute_instance_template_test.go index d4bb4a57f0e..df28d1cd89e 100644 --- a/google/resource_compute_instance_template_test.go +++ b/google/resource_compute_instance_template_test.go @@ -786,6 +786,27 @@ func TestAccComputeInstanceTemplate_shieldedVmConfig2(t *testing.T) { }) } +func TestAccComputeInstanceTemplate_ConfidentialInstanceConfigMain(t *testing.T) { + t.Parallel() + + var instanceTemplate computeBeta.InstanceTemplate + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeInstanceTemplateDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceTemplateConfidentialInstanceConfig(randString(t, 10), true), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeInstanceTemplateExists(t, "google_compute_instance_template.foobar", &instanceTemplate), + testAccCheckComputeInstanceTemplateHasConfidentialInstanceConfig(&instanceTemplate, true), + ), + }, + }, + }) +} + func TestAccComputeInstanceTemplate_enableDisplay(t *testing.T) { t.Parallel() @@ -1205,6 +1226,17 @@ func testAccCheckComputeInstanceTemplateHasShieldedVmConfig(instanceTemplate *co } } +func testAccCheckComputeInstanceTemplateHasConfidentialInstanceConfig(instanceTemplate *computeBeta.InstanceTemplate, EnableConfidentialCompute bool) resource.TestCheckFunc { + + return func(s *terraform.State) error { + if instanceTemplate.Properties.ConfidentialInstanceConfig.EnableConfidentialCompute != EnableConfidentialCompute { + return fmt.Errorf("Wrong ConfidentialInstanceConfig EnableConfidentialCompute: expected %t, got, %t", EnableConfidentialCompute, instanceTemplate.Properties.ConfidentialInstanceConfig.EnableConfidentialCompute) + } + + return nil + } +} + func testAccCheckComputeInstanceTemplateLacksShieldedVmConfig(instanceTemplate *computeBeta.InstanceTemplate) resource.TestCheckFunc { return func(s *terraform.State) error { if instanceTemplate.Properties.ShieldedVmConfig != nil { @@ -2070,6 +2102,39 @@ resource "google_compute_instance_template" "foobar" { `, suffix, enableSecureBoot, enableVtpm, enableIntegrityMonitoring) } +func testAccComputeInstanceTemplateConfidentialInstanceConfig(suffix string, enableConfidentialCompute bool) string { + return fmt.Sprintf(` +data "google_compute_image" "my_image" { + family = "ubuntu-2004-lts" + project = "ubuntu-os-cloud" +} + +resource "google_compute_instance_template" "foobar" { + name = "cvm-%s" + machine_type = "n2d-standard-2" + + disk { + source_image = data.google_compute_image.my_image.self_link + auto_delete = true + boot = true + } + + network_interface { + network = "default" + } + + confidential_instance_config { + enable_confidential_compute = %t + } + + scheduling { + on_host_maintenance = "TERMINATE" + } + +} +`, suffix, enableConfidentialCompute) +} + func testAccComputeInstanceTemplate_enableDisplay(suffix string) string { return fmt.Sprintf(` data "google_compute_image" "my_image" { diff --git a/google/resource_compute_instance_test.go b/google/resource_compute_instance_test.go index 446475a57f5..dd40db1f3ee 100644 --- a/google/resource_compute_instance_test.go +++ b/google/resource_compute_instance_test.go @@ -1288,6 +1288,28 @@ func TestAccComputeInstance_shieldedVmConfig(t *testing.T) { }) } +func TestAccComputeInstanceConfidentialInstanceConfigMain(t *testing.T) { + t.Parallel() + + var instance computeBeta.Instance + instanceName := fmt.Sprintf("tf-test-%s", randString(t, 10)) + + vcrTest(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t), + Steps: []resource.TestStep{ + { + Config: testAccComputeInstanceConfidentialInstanceConfig(instanceName, true), + Check: resource.ComposeTestCheckFunc( + testAccCheckComputeInstanceExists(t, "google_compute_instance.foobar", &instance), + testAccCheckComputeInstanceHasConfidentialInstanceConfig(&instance, true), + ), + }, + }, + }) +} + func TestAccComputeInstance_enableDisplay(t *testing.T) { t.Parallel() @@ -2586,6 +2608,17 @@ func testAccCheckComputeInstanceHasShieldedVmConfig(instance *computeBeta.Instan } } +func testAccCheckComputeInstanceHasConfidentialInstanceConfig(instance *computeBeta.Instance, EnableConfidentialCompute bool) resource.TestCheckFunc { + + return func(s *terraform.State) error { + if instance.ConfidentialInstanceConfig.EnableConfidentialCompute != EnableConfidentialCompute { + return fmt.Errorf("Wrong ConfidentialInstanceConfig EnableConfidentialCompute: expected %t, got, %t", EnableConfidentialCompute, instance.ConfidentialInstanceConfig.EnableConfidentialCompute) + } + + return nil + } +} + func testAccCheckComputeInstanceLacksShieldedVmConfig(instance *computeBeta.Instance) resource.TestCheckFunc { return func(s *terraform.State) error { if instance.ShieldedVmConfig != nil { @@ -4593,6 +4626,40 @@ resource "google_compute_instance" "foobar" { `, instance, enableSecureBoot, enableVtpm, enableIntegrityMonitoring) } +func testAccComputeInstanceConfidentialInstanceConfig(instance string, enableConfidentialCompute bool) string { + return fmt.Sprintf(` +data "google_compute_image" "my_image" { + family = "ubuntu-2004-lts" + project = "ubuntu-os-cloud" +} + +resource "google_compute_instance" "foobar" { + name = "%s" + machine_type = "n2d-standard-2" + zone = "us-central1-a" + + boot_disk { + initialize_params { + image = data.google_compute_image.my_image.self_link + } + } + + network_interface { + network = "default" + } + + confidential_instance_config { + enable_confidential_compute = %t + } + + scheduling { + on_host_maintenance = "TERMINATE" + } + +} +`, instance, enableConfidentialCompute) +} + 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 5f4f603d584..6457ee77ff2 100644 --- a/website/docs/r/compute_instance.html.markdown +++ b/website/docs/r/compute_instance.html.markdown @@ -172,7 +172,7 @@ The following arguments are supported: * `resource_policies` (Optional) -- A list of short names or self_links of resource policies to attach to the instance. Modifying this list will cause the instance to recreate. Currently a max of 1 resource policy is supported. -* `confidential_instance_config` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Enable [Confidential Mode](https://cloud.google.com/compute/confidential-vm/docs/about-cvm) on this VM. +* `confidential_instance_config` (Optional) - Enable [Confidential Mode](https://cloud.google.com/compute/confidential-vm/docs/about-cvm) on this VM. --- @@ -360,7 +360,7 @@ The `shielded_instance_config` block supports: The `confidential_instance_config` block supports: -* `enable_confidential_compute` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Defines whether the instance should have confidential compute enabled. [`on_host_maintenance`](#on_host_maintenance) has to be set to TERMINATE or this will fail to create the VM. +* `enable_confidential_compute` (Optional) Defines whether the instance should have confidential compute enabled. [`on_host_maintenance`](#on_host_maintenance) has to be set to TERMINATE or this will fail to create the VM. ## Attributes Reference diff --git a/website/docs/r/compute_instance_template.html.markdown b/website/docs/r/compute_instance_template.html.markdown index 57d5faef7d4..2e05ae6b65d 100644 --- a/website/docs/r/compute_instance_template.html.markdown +++ b/website/docs/r/compute_instance_template.html.markdown @@ -254,7 +254,7 @@ The following arguments are supported: * `enable_display` - (Optional) Enable [Virtual Displays](https://cloud.google.com/compute/docs/instances/enable-instance-virtual-display#verify_display_driver) on this instance. **Note**: [`allow_stopping_for_update`](#allow_stopping_for_update) must be set to true in order to update this field. -* `confidential_instance_config` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) - Enable [Confidential Mode](https://cloud.google.com/compute/confidential-vm/docs/about-cvm) on this VM. +* `confidential_instance_config` (Optional) - Enable [Confidential Mode](https://cloud.google.com/compute/confidential-vm/docs/about-cvm) on this VM. The `disk` block supports: @@ -421,7 +421,7 @@ The `shielded_instance_config` block supports: The `confidential_instance_config` block supports: -* `enable_confidential_compute` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)) Defines whether the instance should have confidential compute enabled. [`on_host_maintenance`](#on_host_maintenance) has to be set to TERMINATE or this will fail to create the VM. +* `enable_confidential_compute` (Optional) Defines whether the instance should have confidential compute enabled. [`on_host_maintenance`](#on_host_maintenance) has to be set to TERMINATE or this will fail to create the VM. ## Attributes Reference