Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add advanced_machine_features to GCE Instances #3392

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/4849.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:enhancement
compute: added `advanced_machine_features` to `google_compute_instance`
```
2 changes: 0 additions & 2 deletions google-beta/compute_instance_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,6 @@ func expandConfidentialInstanceConfig(d TerraformResourceData) *computeBeta.Conf
prefix := "confidential_instance_config.0"
return &computeBeta.ConfidentialInstanceConfig{
EnableConfidentialCompute: d.Get(prefix + ".enable_confidential_compute").(bool),
ForceSendFields: []string{"EnableSecureBoot"},
}
}

Expand All @@ -354,7 +353,6 @@ func expandAdvancedMachineFeatures(d TerraformResourceData) *computeBeta.Advance
return &computeBeta.AdvancedMachineFeatures{
EnableNestedVirtualization: d.Get(prefix + ".enable_nested_virtualization").(bool),
ThreadsPerCore: int64(d.Get(prefix + ".threads_per_core").(int)),
// ForceSendFields: []string{"EnableSecureBoot"},
}
}

Expand Down
61 changes: 59 additions & 2 deletions google-beta/resource_compute_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,28 @@ func resourceComputeInstance() *schema.Resource {
},
},
},
"advanced_machine_features": {
Type: schema.TypeList,
MaxItems: 1,
Optional: true,
Description: `Controls for advanced machine-related behavior features.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"enable_nested_virtualization": {
Type: schema.TypeBool,
Optional: true,
AtLeastOneOf: []string{"advanced_machine_features.0.enable_nested_virtualization","advanced_machine_features.0.threads_per_core"}
Description: `Whether to enable nested virtualization or not.`,
},
"threads_per_core": {
Type: schema.TypeInt,
Optional: true,
AtLeastOneOf: []string{"advanced_machine_features.0.enable_nested_virtualization","advanced_machine_features.0.threads_per_core"}
Description: `The number of threads per physical core. To disable simultaneous multithreading (SMT) set this to 1. If unset, the maximum number of threads supported per core by the underlying processor is assumed.`,
},
},
},
},
"confidential_instance_config": {
Type: schema.TypeList,
MaxItems: 1,
Expand Down Expand Up @@ -946,6 +968,7 @@ func expandComputeInstance(project string, d *schema.ResourceData, config *Confi
Hostname: d.Get("hostname").(string),
ForceSendFields: []string{"CanIpForward", "DeletionProtection"},
ConfidentialInstanceConfig: expandConfidentialInstanceConfig(d),
AdvancedMachineFeatures: expandAdvancedMachineFeatures(d),
ShieldedInstanceConfig: expandShieldedVmConfigs(d),
DisplayDevice: expandDisplayDevice(d),
ResourcePolicies: convertStringArr(d.Get("resource_policies").([]interface{})),
Expand Down Expand Up @@ -1305,6 +1328,9 @@ func resourceComputeInstanceRead(d *schema.ResourceData, meta interface{}) error
if err := d.Set("confidential_instance_config", flattenConfidentialInstanceConfig(instance.ConfidentialInstanceConfig)); err != nil {
return fmt.Errorf("Error setting confidential_instance_config: %s", err)
}
if err := d.Set("advanced_machine_features", flattenAdvancedMachineFeatures(instance.AdvancedMachineFeatures)); err != nil {
return fmt.Errorf("Error setting advanced_machine_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)
Expand Down Expand Up @@ -1709,7 +1735,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err
}
}

needToStopInstanceBeforeUpdating := scopesChange || d.HasChange("service_account.0.email") || d.HasChange("machine_type") || d.HasChange("min_cpu_platform") || d.HasChange("enable_display") || d.HasChange("shielded_instance_config") || len(updatesToNIWhileStopped) > 0 || bootRequiredSchedulingChange
needToStopInstanceBeforeUpdating := scopesChange || d.HasChange("service_account.0.email") || d.HasChange("machine_type") || d.HasChange("min_cpu_platform") || d.HasChange("enable_display") || d.HasChange("shielded_instance_config") || len(updatesToNIWhileStopped) > 0 || bootRequiredSchedulingChange || d.HasChange("advanced_machine_features")

if d.HasChange("desired_status") && !needToStopInstanceBeforeUpdating {
desiredStatus := d.Get("desired_status").(string)
Expand Down Expand Up @@ -1744,7 +1770,7 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err

if statusBeforeUpdate == "RUNNING" && desiredStatus != "TERMINATED" && !d.Get("allow_stopping_for_update").(bool) {
return fmt.Errorf("Changing the machine_type, min_cpu_platform, service_account, enable_display, shielded_instance_config, scheduling.node_affinities " +
"or network_interface.[#d].(network/subnetwork/subnetwork_project) on a started instance requires stopping it. " +
"or network_interface.[#d].(network/subnetwork/subnetwork_project) or advanced_machine_config on a started instance requires stopping it. " +
"To acknowledge this, please set allow_stopping_for_update = true in your config. " +
"You can also stop it by setting desired_status = \"TERMINATED\", but the instance will not be restarted after the update.")
}
Expand Down Expand Up @@ -1868,6 +1894,37 @@ func resourceComputeInstanceUpdate(d *schema.ResourceData, meta interface{}) err
}
}

if d.HasChange("advanced_machine_features") {
err = retry(
func() error {
// retrieve up-to-date instance from the API in case several updates hit simultaneously. instances
// sometimes but not always share metadata fingerprints.
instance, err := config.NewComputeBetaClient(userAgent).Instances.Get(project, zone, instance.Name).Do()
if err != nil {
return fmt.Errorf("Error retrieving instance: %s", err)
}

instance.AdvancedMachineFeatures = expandAdvancedMachineFeatures(d)

op, err := config.NewComputeBetaClient(userAgent).Instances.Update(project, zone, instance.Name, instance).Do()
if err != nil {
return fmt.Errorf("Error updating instance: %s", err)
}

opErr := computeOperationWaitTime(config, op, project, "advanced_machine_features to update", userAgent, d.Timeout(schema.TimeoutUpdate))
if opErr != nil {
return opErr
}

return nil
},
)

if err != nil {
return err
}
}

// If the instance stops it can invalidate the fingerprint for network interface.
// refresh the instance to get a new fingerprint
if len(updatesToNIWhileStopped) > 0 {
Expand Down
91 changes: 90 additions & 1 deletion google-beta/resource_compute_instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,37 @@ func TestAccComputeInstance_scheduling(t *testing.T) {
})
}

func TestAccComputeInstance_advancedMachineFeatures(t *testing.T) {
t.Parallel()

var instance compute.Instance
var 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: testAccComputeInstance_advancedMachineFeatures(instanceName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists(
t, "google_compute_instance.foobar", &instance),
),
},
computeInstanceImportStep("us-central1-a", instanceName, []string{"allow_stopping_for_update"}),
{
Config: testAccComputeInstance_advancedMachineFeaturesUpdated(instanceName),
Check: resource.ComposeTestCheckFunc(
testAccCheckComputeInstanceExists(
t, "google_compute_instance.foobar", &instance),
),
},
computeInstanceImportStep("us-central1-a", instanceName, []string{"allow_stopping_for_update"}),
},
})
}

func TestAccComputeInstance_soleTenantNodeAffinities(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -1678,7 +1709,7 @@ func TestAccComputeInstance_updateRunning_desiredStatusRunning_allowStoppingForU
})
}

const errorAllowStoppingMsg = "Changing the machine_type, min_cpu_platform, service_account, enable_display, shielded_instance_config, scheduling.node_affinities or network_interface.\\[#d\\].\\(network/subnetwork/subnetwork_project\\) on a started instance requires stopping it. To acknowledge this, please set allow_stopping_for_update = true in your config. You can also stop it by setting desired_status = \"TERMINATED\", but the instance will not be restarted after the update."
const errorAllowStoppingMsg = "Changing the machine_type, min_cpu_platform, service_account, enable_display, shielded_instance_config, scheduling.node_affinities, network_interface.\\[#d\\].\\(network/subnetwork/subnetwork_project\\) or advanced_machine_config on a started instance requires stopping it. To acknowledge this, please set allow_stopping_for_update = true in your config. You can also stop it by setting desired_status = \"TERMINATED\", but the instance will not be restarted after the update."

func TestAccComputeInstance_updateRunning_desiredStatusNotSet_notAllowStoppingForUpdate(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -4241,6 +4272,64 @@ resource "google_compute_instance" "foobar" {
`, instance)
}

func testAccComputeInstance_advancedMachineFeatures(instance string) string {
return fmt.Sprintf(`
data "google_compute_image" "my_image" {
family = "debian-10"
project = "debian-cloud"
}

resource "google_compute_instance" "foobar" {
name = "%s"
machine_type = "n1-standard-2" // Nested Virt isn't supported on E2 and N2Ds https://cloud.google.com/compute/docs/instances/nested-virtualization/overview#restrictions and https://cloud.google.com/compute/docs/instances/disabling-smt#limitations
zone = "us-central1-a"

boot_disk {
initialize_params {
image = data.google_compute_image.my_image.self_link
}
}

network_interface {
network = "default"
}

allow_stopping_for_update = true

}
`, instance)
}

func testAccComputeInstance_advancedMachineFeaturesUpdated(instance string) string {
return fmt.Sprintf(`
data "google_compute_image" "my_image" {
family = "debian-10"
project = "debian-cloud"
}

resource "google_compute_instance" "foobar" {
name = "%s"
machine_type = "n1-standard-2" // Nested Virt isn't supported on E2 and N2Ds https://cloud.google.com/compute/docs/instances/nested-virtualization/overview#restrictions and https://cloud.google.com/compute/docs/instances/disabling-smt#limitations
zone = "us-central1-a"

boot_disk {
initialize_params {
image = data.google_compute_image.my_image.self_link
}
}

network_interface {
network = "default"
}
advanced_machine_features {
threads_per_core = 1
enable_nested_virtualization = true
}
allow_stopping_for_update = true
}
`, instance)
}

func testAccComputeInstance_subnet_auto(suffix, instance string) string {
return fmt.Sprintf(`
data "google_compute_image" "my_image" {
Expand Down
2 changes: 1 addition & 1 deletion google-beta/resource_gke_hub_feature_membership_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
"testing"

"github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl"
dcl "github.com/GoogleCloudPlatform/declarative-resource-client-library/dcl"
gkehub "github.com/GoogleCloudPlatform/declarative-resource-client-library/services/google/gkehub/beta"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
Expand Down
8 changes: 8 additions & 0 deletions website/docs/r/compute_instance.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ The following arguments are supported:

* `confidential_instance_config` (Optional) - Enable [Confidential Mode](https://cloud.google.com/compute/confidential-vm/docs/about-cvm) on this VM.

* `advanced_machine_config` (Optional) - Configure Nested Virtualisation and Simultaneous Hyper Threading on this VM.

* `network_performance_config` (Optional, [Beta](https://terraform.io/docs/providers/google/guides/provider_versions.html)
Configures network performance settings for the instance. Structure is
documented below. **Note**: [`machine_type`](#machine_type) must be a [supported type](https://cloud.google.com/compute/docs/networking/configure-vm-with-high-bandwidth-configuration),
Expand Down Expand Up @@ -380,6 +382,12 @@ The `confidential_instance_config` block supports:

* `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.

The `advanced_machine_features` block supports:

* `enable_nested_virtualization` (Optional) Defines whether the instance should have [nested virtualization](#on_host_maintenance) enabled. Defaults to false.

* `threads_per_core` (Optional) he number of threads per physical core. To disable [simultaneous multithreading (SMT)](https://cloud.google.com/compute/docs/instances/disabling-smt) set this to 1.

The `reservation_affinity` block supports:

* `type` - (Required) The type of reservation from which this instance can consume resources.
Expand Down
4 changes: 2 additions & 2 deletions website/docs/r/compute_instance_template.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ The following arguments are supported:

* `confidential_instance_config` (Optional) - Enable [Confidential Mode](https://cloud.google.com/compute/confidential-vm/docs/about-cvm) on this VM.

* `advanced_machine_features` (Optional) - Configure Nested Virtualisation and Simultaneous Hyper Threading on this VM.
* `advanced_machine_features` (Optional) - Configure Nested Virtualisation and Simultaneous Hyper Threading on this VM.

The `disk` block supports:

Expand Down Expand Up @@ -477,7 +477,7 @@ The `network_performance_config` block supports:

The `advanced_machine_features` block supports:

* `enable_nested_virtualization` (Optional) Defines whether the instance should have [nested virtualization](#on_host_maintenance) enabled. Defaults to false.
* `enable_nested_virtualization` (Optional) Defines whether the instance should have [nested virtualization](#on_host_maintenance) enabled. Defaults to false.

* `threads_per_core` (Optional) he number of threads per physical core. To disable [simultaneous multithreading (SMT)](https://cloud.google.com/compute/docs/instances/disabling-smt) set this to 1.

Expand Down