terraform-plugin-sdk icon indicating copy to clipboard operation
terraform-plugin-sdk copied to clipboard

Custom DiffSuppress method can cause .Get method to return empty results

Open chrisst opened this issue 7 years ago • 0 comments

It looks like there is some unexpected behavior with nested properties when using a custom DiffSuppress method. When creating a new resource there is some custom logic to determine whether a property has changed or not inside of nested objects. However when an address part way down the path returns True from the diffSuppress and then a call to .Get is made to that address it will return an empty state (in this case a empty slice of interfaces).

I've tried to strip down my config / code to the most relevant details below:

Terraform Version

The terraform core is vendored at:

 v  github.com/hashicorp/terraform/helper/config  v0.11.2  v0.11.2

I fetched the latest and was still able to reproduce the issue.

Terraform Configuration Files

example resource:

resource "google_compute_disk" "default" {
  name  = "test-disk"
  image = "debian-9"

  disk_encryption_key {
    raw_key = "some key"
  }

  source_image_encryption_key {
    raw_key = "some other key"
  }
}

Example code

I added the same diff suppress method to both the disk_encryption_key and the source_image_encryption_key which share the same structure/properties, (details can be seen here) but made it so that 1 of the two would be suppressed:

func fakeDiffSuppress(k, old, new string, d *schema.ResourceData) bool {
	if k == "disk_encryption_key.#" {
		log.Println("supressing top level disk_encryption_key diff")
		return true
	}
	return false
}

func resourceComputeDiskCreate(d *schema.ResourceData, meta interface{}) error {
	config := meta.(*Config)
	log.Println("disk_encryption_key is ", d.Get("disk_encryption_key"))
	log.Println("nested disk_encryption_key is ", d.Get("disk_encryption_key.0"))

	log.Println("source_image_encryption_key is ", d.Get("source_image_encryption_key"))
	log.Println("nested source_image_encryption_key is ", d.Get("source_image_encryption_key.0"))

Debug Output

... 2018-10-08T17:15:11.619-0700 [DEBUG] plugin.terraform-provider-google: 2018/10/08 17:15:11 supressing top level disk_encryption_key diff 2018-10-08T17:15:11.620-0700 [DEBUG] plugin.terraform-provider-google: 2018/10/08 17:15:11 supressing top level disk_encryption_key diff google_compute_disk.default: Creating... 2018/10/08 17:15:11 [DEBUG] apply: google_compute_disk.default: executing Apply 2018-10-08T17:15:11.622-0700 [DEBUG] plugin.terraform-provider-google: 2018/10/08 17:15:11 disk_encryption_key is [] 2018-10-08T17:15:11.622-0700 [DEBUG] plugin.terraform-provider-google: 2018/10/08 17:15:11 nested disk_encryption_key is map[kms_key_name: raw_key:some key sha256:] 2018-10-08T17:15:11.622-0700 [DEBUG] plugin.terraform-provider-google: 2018/10/08 17:15:11 source_image_encryption_key is [map[kms_key_name: raw_key:some other key sha256:]] 2018-10-08T17:15:11.622-0700 [DEBUG] plugin.terraform-provider-google: 2018/10/08 17:15:11 nested source_image_encryption_key is map[kms_key_name: raw_key:some other key sha256:]

Expected Behavior

I would expect that regardless of the diff suppress behavior when trying to retrieve a property on a resource from config it would return that property if set.

Actual Behavior

As see in the debug output, when trying to retrieve the property with d.Get("disk_encryption_key") an empty slice is returned. Trying to get details of properties nested even deeper is still possible though.

chrisst avatar Oct 09 '18 00:10 chrisst