Skip to content

Commit dcc0e42

Browse files
compute: Implement graceful switch for metadata_startup_script (#12360) (#8888)
[upstream:b2590d7dcb9f424e419fe8a1fb2c217ade96827f] Signed-off-by: Modular Magician <[email protected]>
1 parent 43fa093 commit dcc0e42

File tree

3 files changed

+123
-1
lines changed

3 files changed

+123
-1
lines changed

.changelog/12360.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:enhancement
2+
compute: made `metadata_startup_script` able to be updated via graceful switch in `google_compute_instance`
3+
```

google-beta/services/compute/resource_compute_instance.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,6 @@ func ResourceComputeInstance() *schema.Resource {
796796
"metadata_startup_script": {
797797
Type: schema.TypeString,
798798
Optional: true,
799-
ForceNew: true,
800799
Description: `Metadata startup scripts made available within the instance.`,
801800
},
802801

@@ -1301,6 +1300,9 @@ be from 0 to 999,999,999 inclusive.`,
13011300
},
13021301
suppressEmptyGuestAcceleratorDiff,
13031302
),
1303+
customdiff.ForceNewIf("metadata_startup_script", func(_ context.Context, d *schema.ResourceDiff, meta interface{}) bool {
1304+
return isGracefulMetadataStartupSwitch(d)
1305+
}),
13041306
validateSubnetworkProject,
13051307
forceNewIfNetworkIPNotUpdatable,
13061308
tpgresource.SetLabelsDiff,
@@ -2950,6 +2952,52 @@ func suppressEmptyGuestAcceleratorDiff(_ context.Context, d *schema.ResourceDiff
29502952
return nil
29512953
}
29522954

2955+
// Function checks whether a graceful switch (without ForceNew) is available
2956+
// between `metadata_startup_script` and `metadata.startup-script`.
2957+
// Graceful switch can be executed in two situations:
2958+
// 1. When `metadata_startup_script` is created with the old value of
2959+
// `metadata.startup-script`.
2960+
// 2. When `metadata_startup_script` is deleted and the old value remains in
2961+
// `metadata.startup-script`
2962+
// For all other changes in `metadata_startup_script`, function sets ForceNew.
2963+
func isGracefulMetadataStartupSwitch(d *schema.ResourceDiff) bool {
2964+
oldMd, newMd := d.GetChange("metadata")
2965+
oldMdMap := oldMd.(map[string]interface{})
2966+
newMdMap := newMd.(map[string]interface{})
2967+
2968+
//No new and old metadata
2969+
if len(oldMdMap) == 0 && len(newMdMap) == 0 {
2970+
return true
2971+
}
2972+
2973+
oldMds, newMds := d.GetChange("metadata_startup_script")
2974+
vMdOld, okOld := oldMdMap["startup-script"]
2975+
vMdNew, okNew := newMdMap["startup-script"]
2976+
2977+
// metadata_startup_script is created
2978+
if oldMds == "" {
2979+
if !okOld {
2980+
return true
2981+
} else if newMds == vMdOld {
2982+
return false
2983+
} else {
2984+
return true
2985+
}
2986+
}
2987+
// metadata_startup_script is deleted
2988+
if newMds == "" {
2989+
if !okNew {
2990+
return true
2991+
} else if oldMds == vMdNew {
2992+
return false
2993+
} else {
2994+
return true
2995+
}
2996+
}
2997+
2998+
return true
2999+
}
3000+
29533001
func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) error {
29543002
config := meta.(*transport_tpg.Config)
29553003
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)

google-beta/services/compute/resource_compute_instance_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,6 +3518,43 @@ func TestAccComputeInstance_metadataStartupScript_update(t *testing.T) {
35183518
})
35193519
}
35203520

3521+
func TestAccComputeInstance_metadataStartupScript_gracefulSwitch(t *testing.T) {
3522+
t.Parallel()
3523+
3524+
var instance compute.Instance
3525+
var instanceName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
3526+
3527+
acctest.VcrTest(t, resource.TestCase{
3528+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3529+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3530+
CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t),
3531+
Steps: []resource.TestStep{
3532+
{
3533+
Config: testAccComputeInstance_metadataStartupScript(instanceName, "e2-medium", "abc"),
3534+
Check: resource.ComposeTestCheckFunc(
3535+
testAccCheckComputeInstanceExists(
3536+
t, "google_compute_instance.foobar", &instance),
3537+
testAccCheckComputeInstanceMetadata(
3538+
&instance, "foo", "abc"),
3539+
testAccCheckComputeInstanceMetadata(
3540+
&instance, "startup-script", "echo hi > /test.txt"),
3541+
),
3542+
},
3543+
{
3544+
Config: testAccComputeInstance_metadataStartupScript_gracefulSwitch(instanceName, "e2-medium", "abc"),
3545+
Check: resource.ComposeTestCheckFunc(
3546+
testAccCheckComputeInstanceExists(
3547+
t, "google_compute_instance.foobar", &instance),
3548+
testAccCheckComputeInstanceMetadata(
3549+
&instance, "foo", "abc"),
3550+
testAccCheckComputeInstanceMetadata(
3551+
&instance, "startup-script", "echo hi > /test.txt"),
3552+
),
3553+
},
3554+
},
3555+
})
3556+
}
3557+
35213558
func TestAccComputeInstance_regionBootDisk(t *testing.T) {
35223559
t.Parallel()
35233560

@@ -9933,6 +9970,40 @@ resource "google_compute_instance" "foobar" {
99339970
`, instance, machineType, metadata)
99349971
}
99359972

9973+
func testAccComputeInstance_metadataStartupScript_gracefulSwitch(instance, machineType, metadata string) string {
9974+
return fmt.Sprintf(`
9975+
data "google_compute_image" "my_image" {
9976+
family = "debian-11"
9977+
project = "debian-cloud"
9978+
}
9979+
9980+
resource "google_compute_instance" "foobar" {
9981+
name = "%s"
9982+
machine_type = "%s"
9983+
zone = "us-central1-a"
9984+
can_ip_forward = false
9985+
tags = ["foo", "bar"]
9986+
9987+
boot_disk {
9988+
initialize_params {
9989+
image = data.google_compute_image.my_image.self_link
9990+
}
9991+
}
9992+
9993+
network_interface {
9994+
network = "default"
9995+
}
9996+
9997+
metadata = {
9998+
foo = "%s"
9999+
startup-script = "echo hi > /test.txt"
10000+
}
10001+
10002+
allow_stopping_for_update = true
10003+
}
10004+
`, instance, machineType, metadata)
10005+
}
10006+
993610007
func testAccComputeInstance_regionBootDisk(instance, diskName, suffix string) string {
993710008
return fmt.Sprintf(`
993810009
resource "google_compute_instance" "regional_vm_instance" {

0 commit comments

Comments
 (0)