From 9080ac09cfb9eb9082118da1196c0a96663ff738 Mon Sep 17 00:00:00 2001 From: Jacob Straszynski Date: Thu, 11 Jan 2018 16:04:10 -0800 Subject: [PATCH] attempt to clear guest accelerator diff --- google/resource_compute_instance.go | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/google/resource_compute_instance.go b/google/resource_compute_instance.go index 611c3dc0975..de3b423e377 100644 --- a/google/resource_compute_instance.go +++ b/google/resource_compute_instance.go @@ -8,6 +8,7 @@ import ( "strings" "github.com/hashicorp/errwrap" + "github.com/hashicorp/terraform/helper/customdiff" "github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/validation" "github.com/mitchellh/hashstructure" @@ -551,6 +552,9 @@ func resourceComputeInstance() *schema.Resource { Deprecated: "Use timeouts block instead.", }, }, + CustomizeDiff: customdiff.All( + suppressEmptyGuestAcceleratorDiff, + ), } } @@ -1219,6 +1223,46 @@ func expandInstanceGuestAccelerators(d TerraformResourceData, config *Config) ([ return guestAccelerators, nil } +// suppressEmptyGuestAcceleratorDiff is used to work around perpetual diff +// issues when a count of `0` guest accelerators is desired. This may occur when +// guest_accelerator support is controlled via a module variable. E.g.: +// +// guest_accelerators { +// count = "${var.enable_gpu ? var.gpu_count : 0}" +// ... +// } +// After reconciling the desired and actual state, we would otherwise see a +// perpetual resembling: +// [] != [{"count":0, "type": "nvidia-tesla-k80"}] +func suppressEmptyGuestAcceleratorDiff(d *schema.ResourceDiff, meta interface{}) error { + oldi, newi := d.GetChange("guest_accelerator") + + old, ok := oldi.([]interface{}) + if !ok { + return fmt.Errorf("Expected old guest accelerator diff to be a slice") + } + + new, ok := newi.([]interface{}) + if !ok { + return fmt.Errorf("Expected new guest accelerator diff to be a slice") + } + + if len(old) != 0 && len(new) != 1 { + return nil + } + + firstAccel, ok := new[0].(map[string]interface{}) + if !ok { + return fmt.Errorf("Unable to type assert guest accelerator") + } + + if firstAccel["count"].(int) == 0 { + d.Clear("guest_accelerator") + } + + return nil +} + func resourceComputeInstanceDelete(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config)