hashicorp / hashicorp/terraform-plugin-sdk
ResourceData.Set() doesn't set empty List/Set of String when Create/Update resource
- Dominant language
- Go
- Stars
- 485
- Forks
- 244
- Avg merge
- 19h 57m
- Merged PRs (30d)
- 4
Description
### SDK version
```
github.com/hashicorp/terraform-plugin-sdk/v2 v2.6.1
```
### Relevant provider source code
#### provider.go
```go
package example
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func Provider() *schema.Provider {
return &schema.Provider{
Schema: map[string]*schema.Schema{},
ResourcesMap: map[string]*schema.Resource{
"example_list": resourceList(),
},
}
}
```
#### resource_list.go
```go
package example
import (
"context"
"log"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func resourceList() *schema.Resource {
return &schema.Resource{
CreateContext: resourceListCreate,
ReadContext: resourceListRead,
UpdateContext: resourceListUpdate,
DeleteContext: resourceListDelete,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"list": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"set": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"list2": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
"set2": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
},
},
}
}
func resourceListCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("Create")
d.SetId(d.Get("name").(string))
return resourceListRead(ctx, d, m)
}
func resourceListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("Read")
v := make([]string, 0)
if err := d.Set("list", v); err != nil {
panic(err)
}
if err := d.Set("set", v); err != nil {
panic(err)
}
return nil
}
func resourceListUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("Update")
v := make([]string, 0)
if err := d.Set("list2", v); err != nil {
panic(err)
}
if err := d.Set("set2", v); err != nil {
panic(err)
}
return resourceListRead(ctx, d, m)
}
func resourceListDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
log.Printf("Delete")
return nil
}
```
### Terraform Configuration Files
```hcl
terraform {
required_providers {
example = {
source = "sdk/example"
}
}
}
resource "example_list" "list" {
name = "test"
}
```
### Debug Output
First apply: https://gist.github.com/jeremmfr/8fdf0aef9a9dba35aa7c2a429013a466
Second apply: https://gist.github.com/jeremmfr/ce7fc52349967f60dbb11845b5839e7a
Especially in second apply :
```hcl
Terraform detected the following changes made outside of Terraform since the last "terraform apply":
# example_list.list has been changed
~ resource "example_list" "list" {
id = "test2"
+ list = []
name = "test2"
+ set = []
}
```
### Expected Behavior
`list` and `set` arguments set in state to an empty list on first apply (create).
### Actual Behavior
`list` and `set` arguments set in state to an empty list only when refresh resource.
With new Terraform version (0.15.4), the note `Note: Objects have changed outside of Terraform` appears for the wrong reason.
### Steps to Reproduce
1. `terraform init`
2. `terraform apply -auto-approve`
3. `terraform apply -auto-approve`
### Others errors
If I update `name` argument, `list2` and `set2` not set to an empty list in state when `apply` (update)
Contributor guide
Research direction
Start with the example provider.go and resource_list.go, reproduce the first and second applies, and compare ResourceData.Set behavior during Create, Update, and Read. Trace the SDK handling of empty TypeList and TypeSet values. Done means empty list and set values persist after create and update without an external-change diff, with regression coverage for both paths.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, terraform
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100