Skip to content

Commit 6b67946

Browse files
compute: Implement graceful switch for metadata_startup_script (#12360) (#20655)
[upstream:b2590d7dcb9f424e419fe8a1fb2c217ade96827f] Signed-off-by: Modular Magician <magic-modules@google.com>
1 parent a78549e commit 6b67946

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/services/compute/resource_compute_instance.go

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,6 @@ func ResourceComputeInstance() *schema.Resource {
760760
"metadata_startup_script": {
761761
Type: schema.TypeString,
762762
Optional: true,
763-
ForceNew: true,
764763
Description: `Metadata startup scripts made available within the instance.`,
765764
},
766765

@@ -1253,6 +1252,9 @@ be from 0 to 999,999,999 inclusive.`,
12531252
},
12541253
suppressEmptyGuestAcceleratorDiff,
12551254
),
1255+
customdiff.ForceNewIf("metadata_startup_script", func(_ context.Context, d *schema.ResourceDiff, meta interface{}) bool {
1256+
return isGracefulMetadataStartupSwitch(d)
1257+
}),
12561258
validateSubnetworkProject,
12571259
forceNewIfNetworkIPNotUpdatable,
12581260
tpgresource.SetLabelsDiff,
@@ -2819,6 +2821,52 @@ func suppressEmptyGuestAcceleratorDiff(_ context.Context, d *schema.ResourceDiff
28192821
return nil
28202822
}
28212823

2824+
// Function checks whether a graceful switch (without ForceNew) is available
2825+
// between `metadata_startup_script` and `metadata.startup-script`.
2826+
// Graceful switch can be executed in two situations:
2827+
// 1. When `metadata_startup_script` is created with the old value of
2828+
// `metadata.startup-script`.
2829+
// 2. When `metadata_startup_script` is deleted and the old value remains in
2830+
// `metadata.startup-script`
2831+
// For all other changes in `metadata_startup_script`, function sets ForceNew.
2832+
func isGracefulMetadataStartupSwitch(d *schema.ResourceDiff) bool {
2833+
oldMd, newMd := d.GetChange("metadata")
2834+
oldMdMap := oldMd.(map[string]interface{})
2835+
newMdMap := newMd.(map[string]interface{})
2836+
2837+
//No new and old metadata
2838+
if len(oldMdMap) == 0 && len(newMdMap) == 0 {
2839+
return true
2840+
}
2841+
2842+
oldMds, newMds := d.GetChange("metadata_startup_script")
2843+
vMdOld, okOld := oldMdMap["startup-script"]
2844+
vMdNew, okNew := newMdMap["startup-script"]
2845+
2846+
// metadata_startup_script is created
2847+
if oldMds == "" {
2848+
if !okOld {
2849+
return true
2850+
} else if newMds == vMdOld {
2851+
return false
2852+
} else {
2853+
return true
2854+
}
2855+
}
2856+
// metadata_startup_script is deleted
2857+
if newMds == "" {
2858+
if !okNew {
2859+
return true
2860+
} else if oldMds == vMdNew {
2861+
return false
2862+
} else {
2863+
return true
2864+
}
2865+
}
2866+
2867+
return true
2868+
}
2869+
28222870
func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) error {
28232871
config := meta.(*transport_tpg.Config)
28242872
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)

google/services/compute/resource_compute_instance_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3341,6 +3341,43 @@ func TestAccComputeInstance_metadataStartupScript_update(t *testing.T) {
33413341
})
33423342
}
33433343

3344+
func TestAccComputeInstance_metadataStartupScript_gracefulSwitch(t *testing.T) {
3345+
t.Parallel()
3346+
3347+
var instance compute.Instance
3348+
var instanceName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
3349+
3350+
acctest.VcrTest(t, resource.TestCase{
3351+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3352+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3353+
CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t),
3354+
Steps: []resource.TestStep{
3355+
{
3356+
Config: testAccComputeInstance_metadataStartupScript(instanceName, "e2-medium", "abc"),
3357+
Check: resource.ComposeTestCheckFunc(
3358+
testAccCheckComputeInstanceExists(
3359+
t, "google_compute_instance.foobar", &instance),
3360+
testAccCheckComputeInstanceMetadata(
3361+
&instance, "foo", "abc"),
3362+
testAccCheckComputeInstanceMetadata(
3363+
&instance, "startup-script", "echo hi > /test.txt"),
3364+
),
3365+
},
3366+
{
3367+
Config: testAccComputeInstance_metadataStartupScript_gracefulSwitch(instanceName, "e2-medium", "abc"),
3368+
Check: resource.ComposeTestCheckFunc(
3369+
testAccCheckComputeInstanceExists(
3370+
t, "google_compute_instance.foobar", &instance),
3371+
testAccCheckComputeInstanceMetadata(
3372+
&instance, "foo", "abc"),
3373+
testAccCheckComputeInstanceMetadata(
3374+
&instance, "startup-script", "echo hi > /test.txt"),
3375+
),
3376+
},
3377+
},
3378+
})
3379+
}
3380+
33443381
func TestAccComputeInstance_regionBootDisk(t *testing.T) {
33453382
t.Parallel()
33463383

@@ -9151,6 +9188,40 @@ resource "google_compute_instance" "foobar" {
91519188
`, instance, machineType, metadata)
91529189
}
91539190

9191+
func testAccComputeInstance_metadataStartupScript_gracefulSwitch(instance, machineType, metadata string) string {
9192+
return fmt.Sprintf(`
9193+
data "google_compute_image" "my_image" {
9194+
family = "debian-11"
9195+
project = "debian-cloud"
9196+
}
9197+
9198+
resource "google_compute_instance" "foobar" {
9199+
name = "%s"
9200+
machine_type = "%s"
9201+
zone = "us-central1-a"
9202+
can_ip_forward = false
9203+
tags = ["foo", "bar"]
9204+
9205+
boot_disk {
9206+
initialize_params {
9207+
image = data.google_compute_image.my_image.self_link
9208+
}
9209+
}
9210+
9211+
network_interface {
9212+
network = "default"
9213+
}
9214+
9215+
metadata = {
9216+
foo = "%s"
9217+
startup-script = "echo hi > /test.txt"
9218+
}
9219+
9220+
allow_stopping_for_update = true
9221+
}
9222+
`, instance, machineType, metadata)
9223+
}
9224+
91549225
func testAccComputeInstance_regionBootDisk(instance, diskName, suffix string) string {
91559226
return fmt.Sprintf(`
91569227
resource "google_compute_instance" "regional_vm_instance" {

0 commit comments

Comments
 (0)