hashicorp / hashicorp/terraform-plugin-sdk

v0.12 regressions: StateFunc is ignored, resource always refreshes

Open
#164 10 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Go
Stars
485
Forks
244
Avg merge
19h 57m
Merged PRs (30d)
4

Description

### Terraform Version

```
Terraform v0.12.2
+ provider.statefunc (unversioned)
```

### Terraform Configuration Files

```hcl
provider "statefunc" {}

resource "statefunc_test" "foo" {
input = "foo"
}

output "foo" {
value = "${statefunc_test.foo.result}"
}
```

### Expected Behavior

Terraform resource is created once and never refreshes.

### Actual Behavior

Resource refreshes on every Terraform run.

### Steps to Reproduce

1. Build testing provider from the code below
2. Take Terraform manifest from snippet above
3. Run Terraform twice.

Reproducible provider code:

```go
package main

import (
"crypto/sha256"
"fmt"

"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/plugin"
"github.com/hashicorp/terraform/terraform"
)

func main() {
plugin.Serve(&plugin.ServeOpts{
ProviderFunc: Provider})
}

func Provider() terraform.ResourceProvider {
return &schema.Provider{
ResourcesMap: map[string]*schema.Resource{
"statefunc_test": resourceTest(),
},
}
}

func resourceTest() *schema.Resource {
return &schema.Resource{
Create: resourceTestCreate,
Read: resourceTestRead,
Delete: resourceTestDelete,

Schema: map[string]*schema.Schema{
"input": &schema.Schema{
Type: schema.TypeString,
Required: true,
ForceNew: true,
StateFunc: sha256sum,
},
"result": &schema.Schema{
Type: schema.TypeString,
Computed: true,
ForceNew: true,
StateFunc: sha256sum,
},
},
}
}

func resourceTestCreate(d *schema.ResourceData, m interface{}) error {
result := sha256sum(d.Get("input"))
d.Set("result", d.Get("input"))
d.SetId(result)

return resourceTestRead(d, m)
}

func resourceTestRead(d *schema.ResourceData, m interface{}) error {
return nil
}

func resourceTestDelete(d *schema.ResourceData, m interface{}) error {
return nil
}

func sha256sum(data interface{}) string {
return fmt.Sprintf("%x", sha256.Sum256([]byte(data.(string))))
}
```

### Additional Context

It seems that here is a regression in v0.12.x regarding applying `SchemeStateFunc`. Following examples are compatible with Terraform v0.11.14 and with this version, problem does not occur and `StateFunc` works as expected.

What the problem here actually is, that despite having `StateFunc` defined, and computed value ends up in state file, without `StateFunc` being applied, as described in hashicorp/terraform-plugin-sdk#163, but this issue is specifically about resources being always refreshed, which is very annoying.

If there is some workaround, which can be implemented on provider side, it would be great.

Here are 2 Terraform state files for additional context:
```json
{
"version": 4,
"terraform_version": "0.12.2",
"serial": 13,
"lineage": "0aecbf07-f3b0-1d56-dae8-c65165388c0c",
"outputs": {
"foo": {
"value": "foo",
"type": "string"
}
},
"resources": [
{
"mode": "managed",
"type": "statefunc_test",
"name": "foo",
"provider": "provider.statefunc",
"instances": [
{
"schema_version": 0,
"attributes": {
"id": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
"input": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
"result": "foo"
},
"private": "bnVsbA=="
}
]
}
]
}
```
```json
{
"version": 3,
"terraform_version": "0.11.14",
"serial": 1,
"lineage": "0b90fab3-40c3-88ff-abbe-3d145632a59b",
"modules": [
{
"path": [
"root"
],
"outputs": {
"foo": {
"sensitive": false,
"type": "string",
"value": "foo"
}
},
"resources": {
"statefunc_test.foo": {
"type": "statefunc_test",
"depends_on": [],
"primary": {
"id": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
"attributes": {
"id": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
"input": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
"result": "foo"
},
"meta": {},
"tainted": false
},
"deposed": [],
"provider": "provider.statefunc"
}
},
"depends_on": []
}
]
}
```

### References

Might be a duplicate of hashicorp/terraform-plugin-sdk#163, though it addresses slightly different issue.

Contributor guide

Open the contributing guide

Research direction

Start with the reproducible Go provider code in the issue, focusing on schema.Resource, StateFunc, and the resource create/read flow. Run the provider with the supplied configuration and execute Terraform twice to confirm the repeated refresh. Done means StateFunc values persist correctly and the resource is not refreshed again without configuration or external state changes.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
tooling
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.