Skip to content

Commit 281059c

Browse files
Add provisioning-model to instance and instance template to support Spot VM for Beta (#5662) (#4033)
Co-authored-by: Shuya Ma <[email protected]> Signed-off-by: Modular Magician <[email protected]> Co-authored-by: Shuya Ma <[email protected]>
1 parent 85a0f68 commit 281059c

12 files changed

+281
-24
lines changed

.changelog/5662.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
```release-note:enhancement
2+
compute: added `provisioning_model` field to `google_compute_instance` resource to support Spot VM(beta)
3+
```
4+
```release-note:enhancement
5+
compute: added `provisioning_model` field to `google_compute_instance_template ` resource to support Spot VM(beta)
6+
```

go.mod

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module github.com/hashicorp/terraform-provider-google-beta
22
require (
33
cloud.google.com/go/bigtable v1.10.1
4+
cloud.google.com/go/iam v0.1.1 // indirect
45
github.com/GoogleCloudPlatform/declarative-resource-client-library v0.0.0-20220125025424-6dfdf699127c
56
github.com/apparentlymart/go-cidr v1.1.0
67
github.com/client9/misspell v0.3.4
@@ -23,8 +24,9 @@ require (
2324
golang.org/x/mod v0.5.0 // indirect
2425
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420
2526
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
26-
google.golang.org/api v0.61.0
27-
google.golang.org/grpc v1.40.0
27+
google.golang.org/api v0.65.0
28+
google.golang.org/grpc v1.40.1
2829
)
2930

31+
3032
go 1.16

go.sum

Lines changed: 67 additions & 20 deletions
Large diffs are not rendered by default.

google-beta/compute_instance_helpers.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ func expandScheduling(v interface{}) (*compute.Scheduling, error) {
118118
if v, ok := original["min_node_cpus"]; ok {
119119
scheduling.MinNodeCpus = int64(v.(int))
120120
}
121-
121+
if v, ok := original["provisioning_model"]; ok {
122+
scheduling.ProvisioningModel = v.(string)
123+
scheduling.ForceSendFields = append(scheduling.ForceSendFields, "ProvisioningModel")
124+
}
122125
return scheduling, nil
123126
}
124127

@@ -127,6 +130,7 @@ func flattenScheduling(resp *compute.Scheduling) []map[string]interface{} {
127130
"on_host_maintenance": resp.OnHostMaintenance,
128131
"preemptible": resp.Preemptible,
129132
"min_node_cpus": resp.MinNodeCpus,
133+
"provisioning_model": resp.ProvisioningModel,
130134
}
131135

132136
if resp.AutomaticRestart != nil {
@@ -471,6 +475,10 @@ func schedulingHasChangeWithoutReboot(d *schema.ResourceData) bool {
471475
return true
472476
}
473477

478+
if oScheduling["provisioning_model"] != newScheduling["provisioning_model"] {
479+
return true
480+
}
481+
474482
return false
475483
}
476484

google-beta/resource_compute_instance.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ var (
4545
"scheduling.0.preemptible",
4646
"scheduling.0.node_affinities",
4747
"scheduling.0.min_node_cpus",
48+
"scheduling.0.provisioning_model",
4849
}
4950

5051
shieldedInstanceConfigKeys = []string{
@@ -620,6 +621,13 @@ func resourceComputeInstance() *schema.Resource {
620621
Optional: true,
621622
AtLeastOneOf: schedulingKeys,
622623
},
624+
"provisioning_model": {
625+
Type: schema.TypeString,
626+
Optional: true,
627+
ForceNew: true,
628+
AtLeastOneOf: schedulingKeys,
629+
Description: `Whether the instance is spot. If this is set as SPOT.`,
630+
},
623631
},
624632
},
625633
},

google-beta/resource_compute_instance_template.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ var (
2323
"scheduling.0.preemptible",
2424
"scheduling.0.node_affinities",
2525
"scheduling.0.min_node_cpus",
26+
"scheduling.0.provisioning_model",
2627
}
2728

2829
shieldedInstanceTemplateConfigKeys = []string{
@@ -528,6 +529,13 @@ func resourceComputeInstanceTemplate() *schema.Resource {
528529
AtLeastOneOf: schedulingInstTemplateKeys,
529530
Description: `Minimum number of cpus for the instance.`,
530531
},
532+
"provisioning_model": {
533+
Type: schema.TypeString,
534+
Optional: true,
535+
ForceNew: true,
536+
AtLeastOneOf: schedulingInstTemplateKeys,
537+
Description: `Whether the instance is spot. If this is set as SPOT.`,
538+
},
531539
},
532540
},
533541
},

google-beta/resource_compute_instance_template_test.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,6 +1073,35 @@ func TestAccComputeInstanceTemplate_queueCount(t *testing.T) {
10731073
})
10741074
}
10751075

1076+
func TestAccComputeInstanceTemplate_spot(t *testing.T) {
1077+
t.Parallel()
1078+
1079+
var instanceTemplate compute.InstanceTemplate
1080+
1081+
vcrTest(t, resource.TestCase{
1082+
PreCheck: func() { testAccPreCheck(t) },
1083+
Providers: testAccProviders,
1084+
CheckDestroy: testAccCheckComputeInstanceTemplateDestroyProducer(t),
1085+
Steps: []resource.TestStep{
1086+
{
1087+
Config: testAccComputeInstanceTemplate_spot(randString(t, 10)),
1088+
Check: resource.ComposeTestCheckFunc(
1089+
testAccCheckComputeInstanceTemplateExists(
1090+
t, "google_compute_instance_template.foobar", &instanceTemplate),
1091+
testAccCheckComputeInstanceTemplateAutomaticRestart(&instanceTemplate, false),
1092+
testAccCheckComputeInstanceTemplatePreemptible(&instanceTemplate, true),
1093+
testAccCheckComputeInstanceTemplateProvisioningModel(&instanceTemplate, "SPOT"),
1094+
),
1095+
},
1096+
{
1097+
ResourceName: "google_compute_instance_template.foobar",
1098+
ImportState: true,
1099+
ImportStateVerify: true,
1100+
},
1101+
},
1102+
})
1103+
}
1104+
10761105
func testAccCheckComputeInstanceTemplateDestroyProducer(t *testing.T) func(s *terraform.State) error {
10771106
return func(s *terraform.State) error {
10781107
config := googleProviderConfig(t)
@@ -1220,6 +1249,15 @@ func testAccCheckComputeInstanceTemplatePreemptible(instanceTemplate *compute.In
12201249
}
12211250
}
12221251

1252+
func testAccCheckComputeInstanceTemplateProvisioningModel(instanceTemplate *compute.InstanceTemplate, provisioning_model string) resource.TestCheckFunc {
1253+
return func(s *terraform.State) error {
1254+
if instanceTemplate.Properties.Scheduling.ProvisioningModel != provisioning_model {
1255+
return fmt.Errorf("Expected provisioning_model %v, got %v", provisioning_model, instanceTemplate.Properties.Scheduling.ProvisioningModel)
1256+
}
1257+
return nil
1258+
}
1259+
}
1260+
12231261
func testAccCheckComputeInstanceTemplateAutomaticRestart(instanceTemplate *compute.InstanceTemplate, automaticRestart bool) resource.TestCheckFunc {
12241262
return func(s *terraform.State) error {
12251263
ar := instanceTemplate.Properties.Scheduling.AutomaticRestart
@@ -2678,3 +2716,43 @@ resource "google_compute_instance_template" "foobar" {
26782716
}
26792717
`, instanceTemplateName)
26802718
}
2719+
2720+
func testAccComputeInstanceTemplate_spot(suffix string) string {
2721+
return fmt.Sprintf(`
2722+
data "google_compute_image" "my_image" {
2723+
family = "debian-9"
2724+
project = "debian-cloud"
2725+
}
2726+
2727+
resource "google_compute_instance_template" "foobar" {
2728+
name = "tf-test-instance-template-%s"
2729+
machine_type = "e2-medium"
2730+
can_ip_forward = false
2731+
tags = ["foo", "bar"]
2732+
2733+
disk {
2734+
source_image = data.google_compute_image.my_image.self_link
2735+
auto_delete = true
2736+
boot = true
2737+
}
2738+
2739+
network_interface {
2740+
network = "default"
2741+
}
2742+
2743+
scheduling {
2744+
preemptible = true
2745+
automatic_restart = false
2746+
provisioning_model = "SPOT"
2747+
}
2748+
2749+
metadata = {
2750+
foo = "bar"
2751+
}
2752+
2753+
service_account {
2754+
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
2755+
}
2756+
}
2757+
`, suffix)
2758+
}

google-beta/resource_compute_instance_test.go

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2210,6 +2210,60 @@ func TestAccComputeInstance_queueCount(t *testing.T) {
22102210
})
22112211
}
22122212

2213+
func TestAccComputeInstance_spotVM(t *testing.T) {
2214+
t.Parallel()
2215+
2216+
var instance compute.Instance
2217+
var instanceName = fmt.Sprintf("tf-test-%s", randString(t, 10))
2218+
2219+
vcrTest(t, resource.TestCase{
2220+
PreCheck: func() { testAccPreCheck(t) },
2221+
Providers: testAccProviders,
2222+
CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t),
2223+
Steps: []resource.TestStep{
2224+
{
2225+
Config: testAccComputeInstance_spotVM(instanceName),
2226+
Check: resource.ComposeTestCheckFunc(
2227+
testAccCheckComputeInstanceExists(
2228+
t, "google_compute_instance.foobar", &instance),
2229+
),
2230+
},
2231+
computeInstanceImportStep("us-central1-a", instanceName, []string{}),
2232+
},
2233+
})
2234+
}
2235+
2236+
func TestAccComputeInstance_spotVM_update(t *testing.T) {
2237+
t.Parallel()
2238+
2239+
var instance compute.Instance
2240+
var instanceName = fmt.Sprintf("tf-test-%s", randString(t, 10))
2241+
2242+
vcrTest(t, resource.TestCase{
2243+
PreCheck: func() { testAccPreCheck(t) },
2244+
Providers: testAccProviders,
2245+
CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t),
2246+
Steps: []resource.TestStep{
2247+
{
2248+
Config: testAccComputeInstance_scheduling(instanceName),
2249+
Check: resource.ComposeTestCheckFunc(
2250+
testAccCheckComputeInstanceExists(
2251+
t, "google_compute_instance.foobar", &instance),
2252+
),
2253+
},
2254+
computeInstanceImportStep("us-central1-a", instanceName, []string{}),
2255+
{
2256+
Config: testAccComputeInstance_spotVM(instanceName),
2257+
Check: resource.ComposeTestCheckFunc(
2258+
testAccCheckComputeInstanceExists(
2259+
t, "google_compute_instance.foobar", &instance),
2260+
),
2261+
},
2262+
computeInstanceImportStep("us-central1-a", instanceName, []string{}),
2263+
},
2264+
})
2265+
}
2266+
22132267
func TestComputeInstance_networkIPCustomizedDiff(t *testing.T) {
22142268
t.Parallel()
22152269

@@ -6170,3 +6224,35 @@ resource "google_compute_instance" "foobar" {
61706224
}
61716225
`, instance)
61726226
}
6227+
6228+
func testAccComputeInstance_spotVM(instance string) string {
6229+
return fmt.Sprintf(`
6230+
data "google_compute_image" "my_image" {
6231+
family = "ubuntu-2004-lts"
6232+
project = "ubuntu-os-cloud"
6233+
}
6234+
6235+
resource "google_compute_instance" "foobar" {
6236+
name = "%s"
6237+
machine_type = "e2-medium"
6238+
zone = "us-central1-a"
6239+
6240+
boot_disk {
6241+
initialize_params {
6242+
image = data.google_compute_image.my_image.self_link
6243+
}
6244+
}
6245+
6246+
network_interface {
6247+
network = "default"
6248+
}
6249+
6250+
scheduling {
6251+
provisioning_model = "SPOT"
6252+
automatic_restart = false
6253+
preemptible = true
6254+
}
6255+
6256+
}
6257+
`, instance)
6258+
}

website/docs/d/compute_instance.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,8 @@ The following arguments are supported:
191191

192192
* `automatic_restart` - Specifies if the instance should be
193193
restarted if it was terminated by Compute Engine (not a user).
194+
195+
* `provisioning_model`(Beta) - Describe the type of preemptible VM.
194196

195197
<a name="nested_guest_accelerator"></a>The `guest_accelerator` block supports:
196198

website/docs/d/compute_instance_template.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ The `disk_encryption_key` block supports:
262262
groups will use as host systems. Read more on sole-tenant node creation
263263
[here](https://cloud.google.com/compute/docs/nodes/create-nodes).
264264
Structure [documented below](#nested_node_affinities).
265+
266+
* `provisioning_model`(Beta) - Describe the type of preemptible VM.
265267

266268
<a name="nested_guest_accelerator"></a>The `guest_accelerator` block supports:
267269

0 commit comments

Comments
 (0)