Skip to content

Commit fe9af5d

Browse files
AsiderramanMahendroo
authored andcommitted
compute: Implement graceful switch for metadata_startup_script (GoogleCloudPlatform#12360)
Signed-off-by: Norbert Kamiński <[email protected]>
1 parent a8780ed commit fe9af5d

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

@@ -1322,6 +1321,9 @@ be from 0 to 999,999,999 inclusive.`,
13221321
},
13231322
suppressEmptyGuestAcceleratorDiff,
13241323
),
1324+
customdiff.ForceNewIf("metadata_startup_script", func(_ context.Context, d *schema.ResourceDiff, meta interface{}) bool {
1325+
return isGracefulMetadataStartupSwitch(d)
1326+
}),
13251327
validateSubnetworkProject,
13261328
forceNewIfNetworkIPNotUpdatable,
13271329
tpgresource.SetLabelsDiff,
@@ -2996,6 +2998,52 @@ func suppressEmptyGuestAcceleratorDiff(_ context.Context, d *schema.ResourceDiff
29962998
return nil
29972999
}
29983000

3001+
// Function checks whether a graceful switch (without ForceNew) is available
3002+
// between `metadata_startup_script` and `metadata.startup-script`.
3003+
// Graceful switch can be executed in two situations:
3004+
// 1. When `metadata_startup_script` is created with the old value of
3005+
// `metadata.startup-script`.
3006+
// 2. When `metadata_startup_script` is deleted and the old value remains in
3007+
// `metadata.startup-script`
3008+
// For all other changes in `metadata_startup_script`, function sets ForceNew.
3009+
func isGracefulMetadataStartupSwitch(d *schema.ResourceDiff) bool {
3010+
oldMd, newMd := d.GetChange("metadata")
3011+
oldMdMap := oldMd.(map[string]interface{})
3012+
newMdMap := newMd.(map[string]interface{})
3013+
3014+
//No new and old metadata
3015+
if len(oldMdMap) == 0 && len(newMdMap) == 0 {
3016+
return true
3017+
}
3018+
3019+
oldMds, newMds := d.GetChange("metadata_startup_script")
3020+
vMdOld, okOld := oldMdMap["startup-script"]
3021+
vMdNew, okNew := newMdMap["startup-script"]
3022+
3023+
// metadata_startup_script is created
3024+
if oldMds == "" {
3025+
if !okOld {
3026+
return true
3027+
} else if newMds == vMdOld {
3028+
return false
3029+
} else {
3030+
return true
3031+
}
3032+
}
3033+
// metadata_startup_script is deleted
3034+
if newMds == "" {
3035+
if !okNew {
3036+
return true
3037+
} else if oldMds == vMdNew {
3038+
return false
3039+
} else {
3040+
return true
3041+
}
3042+
}
3043+
3044+
return true
3045+
}
3046+
29993047
func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) error {
30003048
config := meta.(*transport_tpg.Config)
30013049
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
@@ -3535,6 +3535,43 @@ func TestAccComputeInstance_metadataStartupScript_update(t *testing.T) {
35353535
})
35363536
}
35373537

3538+
func TestAccComputeInstance_metadataStartupScript_gracefulSwitch(t *testing.T) {
3539+
t.Parallel()
3540+
3541+
var instance compute.Instance
3542+
var instanceName = fmt.Sprintf("tf-test-%s", acctest.RandString(t, 10))
3543+
3544+
acctest.VcrTest(t, resource.TestCase{
3545+
PreCheck: func() { acctest.AccTestPreCheck(t) },
3546+
ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t),
3547+
CheckDestroy: testAccCheckComputeInstanceDestroyProducer(t),
3548+
Steps: []resource.TestStep{
3549+
{
3550+
Config: testAccComputeInstance_metadataStartupScript(instanceName, "e2-medium", "abc"),
3551+
Check: resource.ComposeTestCheckFunc(
3552+
testAccCheckComputeInstanceExists(
3553+
t, "google_compute_instance.foobar", &instance),
3554+
testAccCheckComputeInstanceMetadata(
3555+
&instance, "foo", "abc"),
3556+
testAccCheckComputeInstanceMetadata(
3557+
&instance, "startup-script", "echo hi > /test.txt"),
3558+
),
3559+
},
3560+
{
3561+
Config: testAccComputeInstance_metadataStartupScript_gracefulSwitch(instanceName, "e2-medium", "abc"),
3562+
Check: resource.ComposeTestCheckFunc(
3563+
testAccCheckComputeInstanceExists(
3564+
t, "google_compute_instance.foobar", &instance),
3565+
testAccCheckComputeInstanceMetadata(
3566+
&instance, "foo", "abc"),
3567+
testAccCheckComputeInstanceMetadata(
3568+
&instance, "startup-script", "echo hi > /test.txt"),
3569+
),
3570+
},
3571+
},
3572+
})
3573+
}
3574+
35383575
func TestAccComputeInstance_regionBootDisk(t *testing.T) {
35393576
t.Parallel()
35403577

@@ -9976,6 +10013,39 @@ resource "google_compute_instance" "foobar" {
997610013
`, instance, machineType, metadata)
997710014
}
997810015

10016+
func testAccComputeInstance_metadataStartupScript_gracefulSwitch(instance, machineType, metadata string) string {
10017+
return fmt.Sprintf(`
10018+
data "google_compute_image" "my_image" {
10019+
family = "debian-11"
10020+
project = "debian-cloud"
10021+
}
10022+
10023+
resource "google_compute_instance" "foobar" {
10024+
name = "%s"
10025+
machine_type = "%s"
10026+
zone = "us-central1-a"
10027+
can_ip_forward = false
10028+
tags = ["foo", "bar"]
10029+
10030+
boot_disk {
10031+
initialize_params {
10032+
image = data.google_compute_image.my_image.self_link
10033+
}
10034+
}
10035+
10036+
network_interface {
10037+
network = "default"
10038+
}
10039+
10040+
metadata = {
10041+
foo = "%s"
10042+
startup-script = "echo hi > /test.txt"
10043+
}
10044+
10045+
allow_stopping_for_update = true
10046+
}
10047+
`, instance, machineType, metadata)
10048+
}
997910049

998010050
func testAccComputeInstance_regionBootDisk(instance, diskName, suffix string) string {
998110051
return fmt.Sprintf(`

0 commit comments

Comments
 (0)