Skip to content

Commit

Permalink
Stateful MIG -> GA (#4047) (#7429)
Browse files Browse the repository at this point in the history
* Moved stateful MIG resources out of beta

* Ran gofmt on per_instance_config test files

* Promoted instance group manager fields out of beta

* Updated portions of region instance group manager that are out of beta

* Updated docs to not mark stateful_disk as a beta-only field

* Updated links to instance group manager beta docs

Signed-off-by: Modular Magician <[email protected]>
  • Loading branch information
modular-magician authored Oct 5, 2020
1 parent 9594637 commit c4c2bd2
Show file tree
Hide file tree
Showing 16 changed files with 3,119 additions and 7 deletions.
12 changes: 12 additions & 0 deletions .changelog/4047.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
```release-note:enhancement
compute: Marked `stateful_disk` as GA in `google_compute_ instance_group_manager`
```
```release-note:enhancement
compute: Marked `stateful_disk` as GA in `google_compute_ region_instance_group_manager`
```
```release-note:enhancement
compute: Marked `google_compute_ per_instance_config` as GA
```
```release-note:enhancement
compute: Marked `google_compute_ region_per_instance_config` as GA
```
6 changes: 4 additions & 2 deletions google/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -639,9 +639,9 @@ func Provider() *schema.Provider {
return provider
}

// Generated resources: 160
// Generated resources: 162
// Generated IAM resources: 69
// Total generated resources: 229
// Total generated resources: 231
func ResourceMap() map[string]*schema.Resource {
resourceMap, _ := ResourceMapWithErrors()
return resourceMap
Expand Down Expand Up @@ -733,6 +733,8 @@ func ResourceMapWithErrors() (map[string]*schema.Resource, error) {
"google_compute_node_group": resourceComputeNodeGroup(),
"google_compute_network_peering_routes_config": resourceComputeNetworkPeeringRoutesConfig(),
"google_compute_node_template": resourceComputeNodeTemplate(),
"google_compute_per_instance_config": resourceComputePerInstanceConfig(),
"google_compute_region_per_instance_config": resourceComputeRegionPerInstanceConfig(),
"google_compute_region_autoscaler": resourceComputeRegionAutoscaler(),
"google_compute_region_disk": resourceComputeRegionDisk(),
"google_compute_region_disk_iam_binding": ResourceIamBinding(ComputeRegionDiskIamSchema, ComputeRegionDiskIamUpdaterProducer, ComputeRegionDiskIdParseFunc),
Expand Down
63 changes: 62 additions & 1 deletion google/resource_compute_instance_group_manager.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
//
package google

import (
Expand Down Expand Up @@ -263,6 +262,28 @@ func resourceComputeInstanceGroupManager() *schema.Resource {
Default: false,
Description: `Whether to wait for all instances to be created/updated before returning. Note that if this is set to true and the operation does not succeed, Terraform will continue trying until it times out.`,
},
"stateful_disk": {
Type: schema.TypeSet,
Optional: true,
Description: `Disks created on the instances that will be preserved on instance delete, update, etc.`,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"device_name": {
Type: schema.TypeString,
Required: true,
Description: `The device name of the disk to be attached.`,
},

"delete_rule": {
Type: schema.TypeString,
Default: "NEVER",
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"NEVER", "ON_PERMANENT_INSTANCE_DELETION"}, true),
Description: `A value that prescribes what should happen to the stateful disk when the VM instance is deleted. The available options are NEVER and ON_PERMANENT_INSTANCE_DELETION. NEVER detatch the disk when the VM is deleted, but not delete the disk. ON_PERMANENT_INSTANCE_DELETION will delete the stateful disk when the VM is permanently deleted from the instance group. The default is NEVER.`,
},
},
},
},
"operation": {
Type: schema.TypeString,
Computed: true,
Expand Down Expand Up @@ -325,6 +346,7 @@ func resourceComputeInstanceGroupManagerCreate(d *schema.ResourceData, meta inte
AutoHealingPolicies: expandAutoHealingPolicies(d.Get("auto_healing_policies").([]interface{})),
Versions: expandVersions(d.Get("version").([]interface{})),
UpdatePolicy: expandUpdatePolicy(d.Get("update_policy").([]interface{})),
StatefulPolicy: expandStatefulPolicy(d.Get("stateful_disk").(*schema.Set).List()),
// Force send TargetSize to allow a value of 0.
ForceSendFields: []string{"TargetSize"},
}
Expand Down Expand Up @@ -502,6 +524,9 @@ func resourceComputeInstanceGroupManagerRead(d *schema.ResourceData, meta interf
if err = d.Set("named_port", flattenNamedPortsBeta(manager.NamedPorts)); err != nil {
return fmt.Errorf("Error setting named_port in state: %s", err.Error())
}
if err = d.Set("stateful_disk", flattenStatefulPolicy(manager.StatefulPolicy)); err != nil {
return fmt.Errorf("Error setting stateful_disk in state: %s", err.Error())
}
if err := d.Set("fingerprint", manager.Fingerprint); err != nil {
return fmt.Errorf("Error setting fingerprint: %s", err)
}
Expand Down Expand Up @@ -582,6 +607,11 @@ func resourceComputeInstanceGroupManagerUpdate(d *schema.ResourceData, meta inte
change = true
}

if d.HasChange("stateful_disk") {
updatedManager.StatefulPolicy = expandStatefulPolicy(d.Get("stateful_disk").(*schema.Set).List())
change = true
}

if change {
op, err := config.NewComputeBetaClient(userAgent).InstanceGroupManagers.Patch(project, zone, d.Get("name").(string), updatedManager).Do()
if err != nil {
Expand Down Expand Up @@ -716,6 +746,21 @@ func expandAutoHealingPolicies(configured []interface{}) []*computeBeta.Instance
return autoHealingPolicies
}

func expandStatefulPolicy(configured []interface{}) *computeBeta.StatefulPolicy {
disks := make(map[string]computeBeta.StatefulPolicyPreservedStateDiskDevice)
for _, raw := range configured {
data := raw.(map[string]interface{})
disk := computeBeta.StatefulPolicyPreservedStateDiskDevice{
AutoDelete: data["delete_rule"].(string),
}
disks[data["device_name"].(string)] = disk
}
if len(disks) > 0 {
return &computeBeta.StatefulPolicy{PreservedState: &computeBeta.StatefulPolicyPreservedState{Disks: disks}}
}
return nil
}

func expandVersions(configured []interface{}) []*computeBeta.InstanceGroupManagerVersion {
versions := make([]*computeBeta.InstanceGroupManagerVersion, 0, len(configured))
for _, raw := range configured {
Expand Down Expand Up @@ -806,6 +851,22 @@ func flattenAutoHealingPolicies(autoHealingPolicies []*computeBeta.InstanceGroup
return autoHealingPoliciesSchema
}

func flattenStatefulPolicy(statefulPolicy *computeBeta.StatefulPolicy) []map[string]interface{} {
if statefulPolicy == nil || statefulPolicy.PreservedState == nil || statefulPolicy.PreservedState.Disks == nil {
return make([]map[string]interface{}, 0, 0)
}
result := make([]map[string]interface{}, 0, len(statefulPolicy.PreservedState.Disks))
for deviceName, disk := range statefulPolicy.PreservedState.Disks {
data := map[string]interface{}{
"device_name": deviceName,
"delete_rule": disk.AutoDelete,
}

result = append(result, data)
}
return result
}

func flattenUpdatePolicy(updatePolicy *computeBeta.InstanceGroupManagerUpdatePolicy) []map[string]interface{} {
results := []map[string]interface{}{}
if updatePolicy != nil {
Expand Down
182 changes: 182 additions & 0 deletions google/resource_compute_instance_group_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,39 @@ func TestAccInstanceGroupManager_autoHealingPolicies(t *testing.T) {
})
}

func TestAccInstanceGroupManager_stateful(t *testing.T) {
t.Parallel()

template := fmt.Sprintf("tf-test-igm-%s", randString(t, 10))
target := fmt.Sprintf("tf-test-igm-%s", randString(t, 10))
igm := fmt.Sprintf("tf-test-igm-%s", randString(t, 10))
hck := fmt.Sprintf("tf-test-igm-%s", randString(t, 10))

vcrTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckInstanceGroupManagerDestroyProducer(t),
Steps: []resource.TestStep{
{
Config: testAccInstanceGroupManager_stateful(template, target, igm, hck),
},
{
ResourceName: "google_compute_instance_group_manager.igm-basic",
ImportState: true,
ImportStateVerify: true,
},
{
Config: testAccInstanceGroupManager_statefulUpdated(template, target, igm, hck),
},
{
ResourceName: "google_compute_instance_group_manager.igm-basic",
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckInstanceGroupManagerDestroyProducer(t *testing.T) func(s *terraform.State) error {
return func(s *terraform.State) error {
config := googleProviderConfig(t)
Expand Down Expand Up @@ -1183,3 +1216,152 @@ resource "google_compute_instance_group_manager" "igm-basic" {
}
`, primaryTemplate, canaryTemplate, igm)
}

func testAccInstanceGroupManager_stateful(template, target, igm, hck string) string {
return fmt.Sprintf(`
data "google_compute_image" "my_image" {
family = "debian-9"
project = "debian-cloud"
}
resource "google_compute_instance_template" "igm-basic" {
name = "%s"
machine_type = "n1-standard-1"
can_ip_forward = false
tags = ["foo", "bar"]
disk {
source_image = data.google_compute_image.my_image.self_link
auto_delete = true
boot = true
device_name = "my-stateful-disk"
}
disk {
source_image = data.google_compute_image.my_image.self_link
auto_delete = true
device_name = "non-stateful"
}
disk {
source_image = data.google_compute_image.my_image.self_link
auto_delete = true
device_name = "my-stateful-disk2"
}
network_interface {
network = "default"
}
service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}
resource "google_compute_target_pool" "igm-basic" {
description = "Resource created for Terraform acceptance testing"
name = "%s"
session_affinity = "CLIENT_IP_PROTO"
}
resource "google_compute_instance_group_manager" "igm-basic" {
description = "Terraform test instance group manager"
name = "%s"
version {
instance_template = google_compute_instance_template.igm-basic.self_link
name = "prod"
}
target_pools = [google_compute_target_pool.igm-basic.self_link]
base_instance_name = "igm-basic"
zone = "us-central1-c"
target_size = 2
stateful_disk {
device_name = "my-stateful-disk"
delete_rule = "NEVER"
}
}
resource "google_compute_http_health_check" "zero" {
name = "%s"
request_path = "/"
check_interval_sec = 1
timeout_sec = 1
}
`, template, target, igm, hck)
}

func testAccInstanceGroupManager_statefulUpdated(template, target, igm, hck string) string {
return fmt.Sprintf(`
data "google_compute_image" "my_image" {
family = "debian-9"
project = "debian-cloud"
}
resource "google_compute_instance_template" "igm-basic" {
name = "%s"
machine_type = "n1-standard-1"
can_ip_forward = false
tags = ["foo", "bar"]
disk {
source_image = data.google_compute_image.my_image.self_link
auto_delete = true
boot = true
device_name = "my-stateful-disk"
}
disk {
source_image = data.google_compute_image.my_image.self_link
auto_delete = true
device_name = "non-stateful"
}
disk {
source_image = data.google_compute_image.my_image.self_link
auto_delete = true
device_name = "my-stateful-disk2"
}
network_interface {
network = "default"
}
service_account {
scopes = ["userinfo-email", "compute-ro", "storage-ro"]
}
}
resource "google_compute_target_pool" "igm-basic" {
description = "Resource created for Terraform acceptance testing"
name = "%s"
session_affinity = "CLIENT_IP_PROTO"
}
resource "google_compute_instance_group_manager" "igm-basic" {
description = "Terraform test instance group manager"
name = "%s"
version {
instance_template = google_compute_instance_template.igm-basic.self_link
name = "prod"
}
target_pools = [google_compute_target_pool.igm-basic.self_link]
base_instance_name = "igm-basic"
zone = "us-central1-c"
target_size = 2
stateful_disk {
device_name = "my-stateful-disk"
delete_rule = "NEVER"
}
stateful_disk {
device_name = "my-stateful-disk2"
delete_rule = "ON_PERMANENT_INSTANCE_DELETION"
}
}
resource "google_compute_http_health_check" "zero" {
name = "%s"
request_path = "/"
check_interval_sec = 1
timeout_sec = 1
}
`, template, target, igm, hck)
}
Loading

0 comments on commit c4c2bd2

Please sign in to comment.