hashicorp / hashicorp/terraform-plugin-sdk

Returning an error still applies diff to state.

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

Description

### SDK version
present in v1.13.1, not tested in previous versions, still need to determine when the bug was introduced, or if it was intended behavior that wasn't communicated clearly

### Relevant provider source code

```go
func Update(d *schema.ResourceData, meta interface{}) error {
return fmt.Errorf("error")
}
```

### Terraform Configuration Files
For create:

```tf
resource "foo_resource" "testing" {
foo = 123
}
```

For update:

```tf
resource "foo_resource" "testing" {
foo = 456
}
```

### Debug Output
To be added.

### Expected Behavior
On update, because an error is returned, the diff should _not_ be applied to state, so `foo` should still be `123`, as the error indicates that the diff was not used.

### Actual Behavior
On update, `foo` is set to `456` in state, even though the error was correctly returned, indicating that the diff was applied anyways.

### Steps to Reproduce
1. `terraform apply`
2. Modiy `foo` to `456` in config file
3. `terraform apply`
4. `terraform show foo_resource.testing.foo`

### Workarounds

Modifying your code to this correctly discards the diff in the case of error, not applying it to state.

```go
func Update(d *schema.ResourceData, meta interface{}) error {
if err != nil {
d.Partial(true)
return err
}
}
```

### Impact

Most providers shouldn't notice this. The apply will be ended when the error is encountered, so no downstream resources are interpolating incorrect results on the run that errored. And before the next apply, `refresh` should run, updating the information in state to match reality. This should therefore only impact resources that don't or can't update all their fields in `Get`, or users that run with `-refresh=false`, which is discouraged.

Contributor guide

Open the contributing guide

Research direction

Start with the provider Update callback using the supplied failing example and reproduce the behavior with terraform apply and terraform show. Trace how the returned error and ResourceData diff affect state, then verify that a failed update leaves foo at 123 rather than 456; the existing d.Partial(true) workaround provides a comparison point.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, terraform
Domain
devtools
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.