Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stateful MIG -> GA #7429

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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