Skip to content

Commit 72c85af

Browse files
Add support for IGM/RMIG All-Instances Configuration (#6041) (#4506)
Signed-off-by: Modular Magician <[email protected]>
1 parent de055e3 commit 72c85af

7 files changed

+304
-12
lines changed

.changelog/6041.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: added field `all_instances_config` to `google_compute_instance_group_manager` and `google_compute_region_instance_group_manager` (Beta)
3+
```

google-beta/resource_compute_instance_group_manager.go

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ func resourceComputeInstanceGroupManager() *schema.Resource {
2727
Update: schema.DefaultTimeout(15 * time.Minute),
2828
Delete: schema.DefaultTimeout(15 * time.Minute),
2929
},
30-
3130
Schema: map[string]*schema.Schema{
3231
"base_instance_name": {
3332
Type: schema.TypeString,
@@ -267,7 +266,30 @@ func resourceComputeInstanceGroupManager() *schema.Resource {
267266
},
268267
},
269268
},
270-
269+
"all_instances_config": {
270+
Type: schema.TypeList,
271+
Optional: true,
272+
MaxItems: 1,
273+
Description: `Specifies configuration that overrides the instance template configuration for the group.`,
274+
Elem: &schema.Resource{
275+
Schema: map[string]*schema.Schema{
276+
"metadata": {
277+
Type: schema.TypeMap,
278+
Optional: true,
279+
Elem: &schema.Schema{Type: schema.TypeString},
280+
Set: schema.HashString,
281+
Description: `The metadata key-value pairs that you want to patch onto the instance. For more information, see Project and instance metadata,`,
282+
},
283+
"labels": {
284+
Type: schema.TypeMap,
285+
Optional: true,
286+
Elem: &schema.Schema{Type: schema.TypeString},
287+
Set: schema.HashString,
288+
Description: `The label key-value pairs that you want to patch onto the instance,`,
289+
},
290+
},
291+
},
292+
},
271293
"wait_for_instances": {
272294
Type: schema.TypeBool,
273295
Optional: true,
@@ -279,7 +301,8 @@ func resourceComputeInstanceGroupManager() *schema.Resource {
279301
Optional: true,
280302
Default: "STABLE",
281303
ValidateFunc: validation.StringInSlice([]string{"STABLE", "UPDATED"}, false),
282-
Description: `When used with wait_for_instances specifies the status to wait for. When STABLE is specified this resource will wait until the instances are stable before returning. When UPDATED is set, it will wait for the version target to be reached and any per instance configs to be effective as well as all instances to be stable before returning.`,
304+
305+
Description: `When used with wait_for_instances specifies the status to wait for. When STABLE is specified this resource will wait until the instances are stable before returning. When UPDATED is set, it will wait for the version target to be reached and any per instance configs to be effective and all instances configs to be effective as well as all instances to be stable before returning.`,
283306
},
284307
"stateful_disk": {
285308
Type: schema.TypeSet,
@@ -333,6 +356,20 @@ func resourceComputeInstanceGroupManager() *schema.Resource {
333356
},
334357
},
335358
},
359+
"all_instances_config": {
360+
Type: schema.TypeList,
361+
Computed: true,
362+
Description: `Status of all-instances configuration on the group.`,
363+
Elem: &schema.Resource{
364+
Schema: map[string]*schema.Schema{
365+
"effective": {
366+
Type: schema.TypeBool,
367+
Computed: true,
368+
Description: `A bit indicating whether this configuration has been applied to all managed instances in the group.`,
369+
},
370+
},
371+
},
372+
},
336373
"stateful": {
337374
Type: schema.TypeList,
338375
Computed: true,
@@ -423,6 +460,7 @@ func resourceComputeInstanceGroupManagerCreate(d *schema.ResourceData, meta inte
423460
AutoHealingPolicies: expandAutoHealingPolicies(d.Get("auto_healing_policies").([]interface{})),
424461
Versions: expandVersions(d.Get("version").([]interface{})),
425462
UpdatePolicy: expandUpdatePolicy(d.Get("update_policy").([]interface{})),
463+
AllInstancesConfig: expandAllInstancesConfig(nil, d.Get("all_instances_config").([]interface{})),
426464
StatefulPolicy: expandStatefulPolicy(d.Get("stateful_disk").(*schema.Set).List()),
427465
// Force send TargetSize to allow a value of 0.
428466
ForceSendFields: []string{"TargetSize"},
@@ -630,6 +668,11 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf
630668
if err = d.Set("update_policy", flattenUpdatePolicy(manager.UpdatePolicy)); err != nil {
631669
return fmt.Errorf("Error setting update_policy in state: %s", err.Error())
632670
}
671+
if manager.AllInstancesConfig != nil {
672+
if err = d.Set("all_instances_config", flattenAllInstancesConfig(manager.AllInstancesConfig)); err != nil {
673+
return fmt.Errorf("Error setting all_instances_config in state: %s", err.Error())
674+
}
675+
}
633676
if err = d.Set("status", flattenStatus(manager.Status)); err != nil {
634677
return fmt.Errorf("Error setting status in state: %s", err.Error())
635678
}
@@ -695,6 +738,16 @@ func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta inte
695738
change = true
696739
}
697740

741+
if d.HasChange("all_instances_config") {
742+
oldAic, newAic := d.GetChange("all_instances_config")
743+
if newAic == nil || len(newAic.([]interface{})) == 0 {
744+
updatedManager.NullFields = append(updatedManager.NullFields, "AllInstancesConfig")
745+
} else {
746+
updatedManager.AllInstancesConfig = expandAllInstancesConfig(oldAic.([]interface{}), newAic.([]interface{}))
747+
}
748+
change = true
749+
}
750+
698751
if d.HasChange("stateful_disk") {
699752
updatedManager.StatefulPolicy = expandStatefulPolicy(d.Get("stateful_disk").(*schema.Set).List())
700753
change = true
@@ -838,7 +891,7 @@ func resourceComputeInstanceGroupManagerDelete(d *schema.ResourceData, meta inte
838891
func computeIGMWaitForInstanceStatus(d *schema.ResourceData, meta interface{}) error {
839892
waitForUpdates := d.Get("wait_for_instances_status").(string) == "UPDATED"
840893
conf := resource.StateChangeConf{
841-
Pending: []string{"creating", "error", "updating per instance configs", "reaching version target"},
894+
Pending: []string{"creating", "error", "updating per instance configs", "reaching version target", "updating all instances config"},
842895
Target: []string{"created"},
843896
Refresh: waitForInstancesRefreshFunc(getManager, waitForUpdates, d, meta),
844897
Timeout: d.Timeout(schema.TimeoutCreate),
@@ -1020,13 +1073,68 @@ func flattenUpdatePolicy(updatePolicy *compute.InstanceGroupManagerUpdatePolicy)
10201073
return results
10211074
}
10221075

1076+
func expandAllInstancesConfig(old []interface{}, new []interface{}) *compute.InstanceGroupManagerAllInstancesConfig {
1077+
var properties *compute.InstancePropertiesPatch
1078+
for _, raw := range new {
1079+
properties = &compute.InstancePropertiesPatch{}
1080+
data := raw.(map[string]interface{})
1081+
properties.Metadata = convertStringMap(data["metadata"].(map[string]interface{}))
1082+
if len(properties.Metadata) == 0 {
1083+
properties.NullFields = append(properties.NullFields, "Metadata")
1084+
}
1085+
properties.Labels = convertStringMap(data["labels"].(map[string]interface{}))
1086+
if len(properties.Labels) == 0 {
1087+
properties.NullFields = append(properties.NullFields, "Labels")
1088+
}
1089+
}
1090+
1091+
if properties != nil {
1092+
for _, raw := range old {
1093+
data := raw.(map[string]interface{})
1094+
for k := range data["metadata"].(map[string]interface{}) {
1095+
if _, exist := properties.Metadata[k]; !exist {
1096+
properties.NullFields = append(properties.NullFields, fmt.Sprintf("Metadata.%s", k))
1097+
}
1098+
}
1099+
for k := range data["labels"].(map[string]interface{}) {
1100+
if _, exist := properties.Labels[k]; !exist {
1101+
properties.NullFields = append(properties.NullFields, fmt.Sprintf("Labels.%s", k))
1102+
}
1103+
}
1104+
}
1105+
}
1106+
if properties != nil {
1107+
allInstancesConfig := &compute.InstanceGroupManagerAllInstancesConfig{}
1108+
allInstancesConfig.Properties = properties
1109+
return allInstancesConfig
1110+
} else {
1111+
return nil
1112+
}
1113+
}
1114+
1115+
func flattenAllInstancesConfig(allInstancesConfig *compute.InstanceGroupManagerAllInstancesConfig) []map[string]interface{} {
1116+
results := []map[string]interface{}{}
1117+
props := map[string]interface{}{}
1118+
if len(allInstancesConfig.Properties.Metadata) > 0 {
1119+
props["metadata"] = allInstancesConfig.Properties.Metadata
1120+
}
1121+
if len(allInstancesConfig.Properties.Labels) > 0 {
1122+
props["labels"] = allInstancesConfig.Properties.Labels
1123+
}
1124+
results = append(results, props)
1125+
return results
1126+
}
1127+
10231128
func flattenStatus(status *compute.InstanceGroupManagerStatus) []map[string]interface{} {
10241129
results := []map[string]interface{}{}
10251130
data := map[string]interface{}{
10261131
"is_stable": status.IsStable,
10271132
"stateful": flattenStatusStateful(status.Stateful),
10281133
"version_target": flattenStatusVersionTarget(status.VersionTarget),
10291134
}
1135+
if status.AllInstancesConfig != nil {
1136+
data["all_instances_config"] = flattenStatusAllInstancesConfig(status.AllInstancesConfig)
1137+
}
10301138
results = append(results, data)
10311139
return results
10321140
}
@@ -1059,6 +1167,15 @@ func flattenStatusVersionTarget(versionTarget *compute.InstanceGroupManagerStatu
10591167
return results
10601168
}
10611169

1170+
func flattenStatusAllInstancesConfig(allInstancesConfig *compute.InstanceGroupManagerStatusAllInstancesConfig) []map[string]interface{} {
1171+
results := []map[string]interface{}{}
1172+
data := map[string]interface{}{
1173+
"effective": allInstancesConfig.Effective,
1174+
}
1175+
results = append(results, data)
1176+
return results
1177+
}
1178+
10621179
func resourceInstanceGroupManagerStateImporter(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
10631180
if err := d.Set("wait_for_instances", false); err != nil {
10641181
return nil, fmt.Errorf("Error setting wait_for_instances: %s", err)

google-beta/resource_compute_instance_group_manager_test.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,14 @@ resource "google_compute_instance_group_manager" "igm-update" {
608608
name = "customhttp"
609609
port = 8080
610610
}
611+
all_instances_config {
612+
metadata = {
613+
foo = "bar"
614+
}
615+
labels = {
616+
doo = "dad"
617+
}
618+
}
611619
}
612620
`, template, target, description, igm)
613621
}
@@ -698,6 +706,15 @@ resource "google_compute_instance_group_manager" "igm-update" {
698706
name = "customhttps"
699707
port = 8443
700708
}
709+
710+
all_instances_config {
711+
metadata = {
712+
doo = "dad"
713+
}
714+
labels = {
715+
foo = "bar"
716+
}
717+
}
701718
}
702719
`, template1, target1, target2, template2, description, igm)
703720
}
@@ -1579,11 +1596,26 @@ resource "google_compute_instance_group_manager" "igm-basic" {
15791596
name = "%s"
15801597
version {
15811598
instance_template = google_compute_instance_template.igm-basic.self_link
1582-
name = "prod"
1599+
name = "prod2"
15831600
}
15841601
target_pools = [google_compute_target_pool.igm-basic.self_link]
15851602
base_instance_name = "tf-test-igm-basic"
15861603
zone = "us-central1-c"
1604+
update_policy {
1605+
type = "PROACTIVE"
1606+
minimal_action = "REPLACE"
1607+
replacement_method = "RECREATE"
1608+
max_surge_fixed = 0
1609+
max_unavailable_percent = 50
1610+
}
1611+
all_instances_config {
1612+
metadata = {
1613+
doo = "dad"
1614+
}
1615+
labels = {
1616+
foo = "bar"
1617+
}
1618+
}
15871619
wait_for_instances = true
15881620
wait_for_instances_status = "UPDATED"
15891621
}

google-beta/resource_compute_region_instance_group_manager.go

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ func resourceComputeRegionInstanceGroupManager() *schema.Resource {
180180
Optional: true,
181181
Default: "STABLE",
182182
ValidateFunc: validation.StringInSlice([]string{"STABLE", "UPDATED"}, false),
183-
Description: `When used with wait_for_instances specifies the status to wait for. When STABLE is specified this resource will wait until the instances are stable before returning. When UPDATED is set, it will wait for the version target to be reached and any per instance configs to be effective as well as all instances to be stable before returning.`,
183+
184+
Description: `When used with wait_for_instances specifies the status to wait for. When STABLE is specified this resource will wait until the instances are stable before returning. When UPDATED is set, it will wait for the version target to be reached and any per instance configs to be effective and all instances configs to be effective as well as all instances to be stable before returning.`,
184185
},
185186

186187
"auto_healing_policies": {
@@ -312,7 +313,30 @@ func resourceComputeRegionInstanceGroupManager() *schema.Resource {
312313
},
313314
},
314315
},
315-
316+
"all_instances_config": {
317+
Type: schema.TypeList,
318+
Optional: true,
319+
MaxItems: 1,
320+
Description: `Specifies configuration that overrides the instance template configuration for the group.`,
321+
Elem: &schema.Resource{
322+
Schema: map[string]*schema.Schema{
323+
"metadata": {
324+
Type: schema.TypeMap,
325+
Optional: true,
326+
Elem: &schema.Schema{Type: schema.TypeString},
327+
Set: schema.HashString,
328+
Description: `The metadata key-value pairs that you want to patch onto the instance. For more information, see Project and instance metadata,`,
329+
},
330+
"labels": {
331+
Type: schema.TypeMap,
332+
Optional: true,
333+
Elem: &schema.Schema{Type: schema.TypeString},
334+
Set: schema.HashString,
335+
Description: `The label key-value pairs that you want to patch onto the instance,`,
336+
},
337+
},
338+
},
339+
},
316340
"stateful_disk": {
317341
Type: schema.TypeSet,
318342
Optional: true,
@@ -361,6 +385,20 @@ func resourceComputeRegionInstanceGroupManager() *schema.Resource {
361385
},
362386
},
363387
},
388+
"all_instances_config": {
389+
Type: schema.TypeList,
390+
Computed: true,
391+
Description: `Status of all-instances configuration on the group.`,
392+
Elem: &schema.Resource{
393+
Schema: map[string]*schema.Schema{
394+
"effective": {
395+
Type: schema.TypeBool,
396+
Computed: true,
397+
Description: `A bit indicating whether this configuration has been applied to all managed instances in the group.`,
398+
},
399+
},
400+
},
401+
},
364402
"stateful": {
365403
Type: schema.TypeList,
366404
Computed: true,
@@ -424,6 +462,7 @@ func resourceComputeRegionInstanceGroupManagerCreate(d *schema.ResourceData, met
424462
AutoHealingPolicies: expandAutoHealingPolicies(d.Get("auto_healing_policies").([]interface{})),
425463
Versions: expandVersions(d.Get("version").([]interface{})),
426464
UpdatePolicy: expandRegionUpdatePolicy(d.Get("update_policy").([]interface{})),
465+
AllInstancesConfig: expandAllInstancesConfig(nil, d.Get("all_instances_config").([]interface{})),
427466
DistributionPolicy: expandDistributionPolicy(d),
428467
StatefulPolicy: expandStatefulPolicy(d.Get("stateful_disk").(*schema.Set).List()),
429468
// Force send TargetSize to allow size of 0.
@@ -461,7 +500,7 @@ func resourceComputeRegionInstanceGroupManagerCreate(d *schema.ResourceData, met
461500
func computeRIGMWaitForInstanceStatus(d *schema.ResourceData, meta interface{}) error {
462501
waitForUpdates := d.Get("wait_for_instances_status").(string) == "UPDATED"
463502
conf := resource.StateChangeConf{
464-
Pending: []string{"creating", "error", "updating per instance configs", "reaching version target"},
503+
Pending: []string{"creating", "error", "updating per instance configs", "reaching version target", "updating all instances config"},
465504
Target: []string{"created"},
466505
Refresh: waitForInstancesRefreshFunc(getRegionalManager, waitForUpdates, d, meta),
467506
Timeout: d.Timeout(schema.TimeoutCreate),
@@ -520,6 +559,12 @@ func waitForInstancesRefreshFunc(f getInstanceManagerFunc, waitForUpdates bool,
520559
if !m.Status.VersionTarget.IsReached {
521560
return false, "reaching version target", nil
522561
}
562+
if !m.Status.VersionTarget.IsReached {
563+
return false, "reaching version target", nil
564+
}
565+
if !m.Status.AllInstancesConfig.Effective {
566+
return false, "updating all instances config", nil
567+
}
523568
}
524569
return true, "created", nil
525570
} else {
@@ -595,6 +640,11 @@ func resourceComputeRegionInstanceGroupManagerRead(d *schema.ResourceData, meta
595640
if err := d.Set("update_policy", flattenRegionUpdatePolicy(manager.UpdatePolicy)); err != nil {
596641
return fmt.Errorf("Error setting update_policy in state: %s", err.Error())
597642
}
643+
if manager.AllInstancesConfig != nil {
644+
if err = d.Set("all_instances_config", flattenAllInstancesConfig(manager.AllInstancesConfig)); err != nil {
645+
return fmt.Errorf("Error setting all_instances_config in state: %s", err.Error())
646+
}
647+
}
598648
if err = d.Set("stateful_disk", flattenStatefulPolicy(manager.StatefulPolicy)); err != nil {
599649
return fmt.Errorf("Error setting stateful_disk in state: %s", err.Error())
600650
}
@@ -657,6 +707,16 @@ func resourceComputeRegionInstanceGroupManagerUpdate(d *schema.ResourceData, met
657707
change = true
658708
}
659709

710+
if d.HasChange("all_instances_config") {
711+
oldAic, newAic := d.GetChange("all_instances_config")
712+
if newAic == nil || len(newAic.([]interface{})) == 0 {
713+
updatedManager.NullFields = append(updatedManager.NullFields, "AllInstancesConfig")
714+
} else {
715+
updatedManager.AllInstancesConfig = expandAllInstancesConfig(oldAic.([]interface{}), newAic.([]interface{}))
716+
}
717+
change = true
718+
}
719+
660720
if d.HasChange("stateful_disk") {
661721
updatedManager.StatefulPolicy = expandStatefulPolicy(d.Get("stateful_disk").(*schema.Set).List())
662722
change = true

0 commit comments

Comments
 (0)