hashicorp / hashicorp/terraform-plugin-sdk
Custom DiffSuppress method can cause .Get method to return empty results
- Dominant language
- Go
- Stars
- 485
- Forks
- 244
- Avg merge
- 19h 57m
- Merged PRs (30d)
- 4
Description
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:
```hcl
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](https://www.terraform.io/docs/providers/google/r/compute_disk.html#raw_key-2)) 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.
Contributor guide
Research direction
Start with fakeDiffSuppress and resourceComputeDiskCreate, reproducing the nested disk_encryption_key and source_image_encryption_key d.Get calls shown in the report. Trace how DiffSuppress affects nested values and verify that d.Get("disk_encryption_key") preserves configured data while deeper lookups continue to work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, terraform
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100