Skip to content

Commit 3eb8e86

Browse files
committed
compute: Implement graceful switch for metadata_startup_script
This patch checks whether a graceful switch (without ForceNew) is available between `metadata_startup_script` and `metadata.startup-script`. Graceful switch can be executed in two situations: 1. When `metadata_startup_script` is created with the old value of `metadata.startup-script`. 2. When `metadata_startup_script` is deleted and the old value remains in `metadata.startup-script` For all other changes in `metadata_startup_script`, function sets ForceNew. Also it adds TestAccComputeInstance_metadataStartupScript_gracefulSwitch test that covers those changes. Closes: hashicorp/terraform-provider-google#9459 Signed-off-by: Norbert Kamiński <[email protected]>
1 parent 3efe5e8 commit 3eb8e86

File tree

2 files changed

+119
-1
lines changed

2 files changed

+119
-1
lines changed

mmv1/third_party/terraform/services/compute/resource_compute_instance.go.tmpl

+49-1
Original file line numberDiff line numberDiff line change
@@ -815,7 +815,6 @@ func ResourceComputeInstance() *schema.Resource {
815815
"metadata_startup_script": {
816816
Type: schema.TypeString,
817817
Optional: true,
818-
ForceNew: true,
819818
Description: `Metadata startup scripts made available within the instance.`,
820819
},
821820

@@ -1315,6 +1314,9 @@ be from 0 to 999,999,999 inclusive.`,
13151314
},
13161315
suppressEmptyGuestAcceleratorDiff,
13171316
),
1317+
customdiff.ForceNewIf("metadata_startup_script", func(_ context.Context, d *schema.ResourceDiff, meta interface{}) bool {
1318+
return isGracefulMetadataStartupSwitch(d)
1319+
}),
13181320
validateSubnetworkProject,
13191321
forceNewIfNetworkIPNotUpdatable,
13201322
tpgresource.SetLabelsDiff,
@@ -2977,6 +2979,52 @@ func suppressEmptyGuestAcceleratorDiff(_ context.Context, d *schema.ResourceDiff
29772979
return nil
29782980
}
29792981

2982+
// Function checks whether a graceful switch (without ForceNew) is available
2983+
// between `metadata_startup_script` and `metadata.startup-script`.
2984+
// Graceful switch can be executed in two situations:
2985+
// 1. When `metadata_startup_script` is created with the old value of
2986+
// `metadata.startup-script`.
2987+
// 2. When `metadata_startup_script` is deleted and the old value remains in
2988+
// `metadata.startup-script`
2989+
// For all other changes in `metadata_startup_script`, function sets ForceNew.
2990+
func isGracefulMetadataStartupSwitch(d *schema.ResourceDiff) bool {
2991+
oldMd, newMd := d.GetChange("metadata")
2992+
oldMdMap := oldMd.(map[string]interface{})
2993+
newMdMap := newMd.(map[string]interface{})
2994+
2995+
//No new and old metadata
2996+
if len(oldMdMap) == 0 && len(newMdMap) == 0 {
2997+
return true
2998+
}
2999+
3000+
oldMds, newMds := d.GetChange("metadata_startup_script")
3001+
vMdOld, okOld := oldMdMap["startup-script"]
3002+
vMdNew, okNew := newMdMap["startup-script"]
3003+
3004+
// metadata_startup_script is created
3005+
if oldMds == "" {
3006+
if !okOld {
3007+
return true
3008+
} else if newMds == vMdOld {
3009+
return false
3010+
} else {
3011+
return true
3012+
}
3013+
}
3014+
// metadata_startup_script is deleted
3015+
if newMds == "" {
3016+
if !okNew {
3017+
return true
3018+
} else if oldMds == vMdNew {
3019+
return false
3020+
} else {
3021+
return true
3022+
}
3023+
}
3024+
3025+
return true
3026+
}
3027+
29803028
func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) error {
29813029
config := meta.(*transport_tpg.Config)
29823030
userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent)

mmv1/third_party/terraform/services/compute/resource_compute_instance_test.go.tmpl

+70
Original file line numberDiff line numberDiff line change
@@ -3508,6 +3508,43 @@ func TestAccComputeInstance_metadataStartupScript_update(t *testing.T) {
35083508
})
35093509
}
35103510

3511+
func TestAccComputeInstance_metadataStartupScript_gracefulSwitch(t *testing.T) {
3512+
t.Parallel()
3513+
3514+
var instance compute.Instance
3515+
var instanceName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
3516+
3517+
acctest.VcrTest(t, resource.TestCase{
3518+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3519+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3520+
CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t),
3521+
Steps: []resource.TestStep{
3522+
{
3523+
Config: testAccComputeInstance_metadataStartupScript(instanceName, "e2-medium", "abc"),
3524+
Check: resource.ComposeTestCheckFunc(
3525+
testAccCheckComputeInstanceExists(
3526+
t, "google_compute_instance.foobar", &instance),
3527+
testAccCheckComputeInstanceMetadata(
3528+
&instance, "foo", "abc"),
3529+
testAccCheckComputeInstanceMetadata(
3530+
&instance, "startup-script", "echo hi > /test.txt"),
3531+
),
3532+
},
3533+
{
3534+
Config: testAccComputeInstance_metadataStartupScript_gracefulSwitch(instanceName, "e2-medium", "abc"),
3535+
Check: resource.ComposeTestCheckFunc(
3536+
testAccCheckComputeInstanceExists(
3537+
t, "google_compute_instance.foobar", &instance),
3538+
testAccCheckComputeInstanceMetadata(
3539+
&instance, "foo", "abc"),
3540+
testAccCheckComputeInstanceMetadata(
3541+
&instance, "startup-script", "echo hi > /test.txt"),
3542+
),
3543+
},
3544+
},
3545+
})
3546+
}
3547+
35113548
func TestAccComputeInstance_regionBootDisk(t *testing.T) {
35123549
t.Parallel()
35133550

@@ -9877,6 +9914,39 @@ resource "google_compute_instance" "foobar" {
98779914
`, instance, machineType, metadata)
98789915
}
98799916

9917+
func testAccComputeInstance_metadataStartupScript_gracefulSwitch(instance, machineType, metadata string) string {
9918+
return fmt.Sprintf(`
9919+
data "google_compute_image" "my_image" {
9920+
family = "debian-11"
9921+
project = "debian-cloud"
9922+
}
9923+
9924+
resource "google_compute_instance" "foobar" {
9925+
name = "%s"
9926+
machine_type = "%s"
9927+
zone = "us-central1-a"
9928+
can_ip_forward = false
9929+
tags = ["foo", "bar"]
9930+
9931+
boot_disk {
9932+
initialize_params {
9933+
image = data.google_compute_image.my_image.self_link
9934+
}
9935+
}
9936+
9937+
network_interface {
9938+
network = "default"
9939+
}
9940+
9941+
metadata = {
9942+
foo = "%s"
9943+
startup-script = "echo hi > /test.txt"
9944+
}
9945+
9946+
allow_stopping_for_update = true
9947+
}
9948+
`, instance, machineType, metadata)
9949+
}
98809950

98819951
func testAccComputeInstance_regionBootDisk(instance, diskName, suffix string) string {
98829952
return fmt.Sprintf(`

0 commit comments

Comments
 (0)