Skip to content

Provider does not work with terraform refresh #130

@corlettb

Description

@corlettb

First of all, thanks for this project. I've used it a few times over the last few years where there has been a provider shortfall.

Recently I tried to use this provider to help bring terraform up-to-date with a resource that can sometimes change outside of terraform. Not ideal I know.

I assumed I could put logic into the read shell script so that the terraform refresh would pick up the new state.

However, this does not work. Following a plan where the read.sh has an updated output since the last terraform apply, we see a pending change (Nothing should be showing as a refresh was done).

resource "shell_script" "definition" {
 ~ dirty             = true -> false
    id                = "cmfviei42r3c0p1gni10"
    # (3 unchanged attributes hidden)

    # (1 unchanged block hidden)
}

The plan will also show a revert pending on resources that depend upon the outputs:

resource "example" "main" {
        id                                 = "1234"
      ~ definition                    = "629" -> "628"
        # (15 unchanged attributes hidden)

        # (6 unchanged blocks hidden)
    }

If you try to then do a terraform apply you get the following error:

│ Error: Provider produced inconsistent final plan
│ 
│ When expanding the plan for example.main to include new values learned so far during apply, provider "registry.example.provider" produced an invalid new value for .defintion: was
│ cty.StringVal("628"), but now cty.StringVal("629").
│ 
│ This is a bug in the provider, which should be reported in the provider's own issue tracker.

After looking through the code for read I can see the issue being around this logic in the read function.

	log.Printf("[DEBUG] previous output:|%v|", previousOutput)
	log.Printf("[DEBUG] new output:|%v|", output)
	isStateEqual := reflect.DeepEqual(output, previousOutput)
	isNewResource := d.IsNewResource()
	isUpdatedResource := stack[0] == ActionUpdate
	if !isStateEqual && !isNewResource && !isUpdatedResource {
		log.Printf("[DEBUG] Previous state not equal to new state. Marking resource as dirty to trigger update.")
		d.Set("dirty", true)
		return nil
	}

	d.Set("output", output)

	return nil

Namely during a refresh it won't update output from the shell script, it will simply update the dirty flag to true and return.

I tried a fork and removed this logic, instead just doing a d.Set("output", output) and this corrected the issue.

I'm guessing the dirty flag is there because we have no way to tell terraform the input environment variables are not the same as when this was deployed and so the resource needs to be updated. I could create a pull request to add an option to disable this functionality and just update the output in the state.

Would love your thoughts.

Thanks again.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions