don't append refreshed state dependencies

EvalRefreshDependencies is used to update resource dependencies when
they don't exist, allow broken or old states to be updated. While
appending any newly found dependencies is tempting to have the largest
set available, changes to the config could conflict with the prior
dependencies causing cycles.
This commit is contained in:
James Bardin 2019-11-15 16:00:13 -05:00
parent 682083cdd1
commit 33bef7c42e
2 changed files with 21 additions and 14 deletions

View File

@ -1978,6 +1978,17 @@ func TestRefresh_updateDependencies(t *testing.T) {
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
AttrsJSON: []byte(`{"id":"foo"}`),
Dependencies: []addrs.AbsResource{
// Existing dependencies should not be removed during refresh
{
Module: addrs.RootModuleInstance,
Resource: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "aws_instance",
Name: "baz",
},
},
},
},
addrs.ProviderConfig{
Type: "aws",
@ -1992,17 +2003,6 @@ func TestRefresh_updateDependencies(t *testing.T) {
&states.ResourceInstanceObjectSrc{
Status: states.ObjectReady,
AttrsJSON: []byte(`{"id":"bar","foo":"foo"}`),
Dependencies: []addrs.AbsResource{
// Existing dependencies should not be removed during refresh
{
Module: addrs.RootModuleInstance,
Resource: addrs.Resource{
Mode: addrs.ManagedResourceMode,
Type: "aws_instance",
Name: "baz",
},
},
},
},
addrs.ProviderConfig{
Type: "aws",
@ -2045,11 +2045,13 @@ aws_instance.bar:
foo = foo
Dependencies:
aws_instance.baz
aws_instance.foo
aws_instance.foo:
ID = foo
provider = provider.aws
Dependencies:
aws_instance.baz
`)
checkStateString(t, result, expect)

View File

@ -508,8 +508,13 @@ func (n *EvalRefreshDependencies) Eval(ctx EvalContext) (interface{}, error) {
depMap[d.String()] = d
}
for _, d := range state.Dependencies {
depMap[d.String()] = d
// We have already dependencies in state, so we need to trust those for
// refresh. We can't write out new dependencies until apply time in case
// the configuration has been changed in a manner the conflicts with the
// stored dependencies.
if len(state.Dependencies) > 0 {
*n.Dependencies = state.Dependencies
return nil, nil
}
deps := make([]addrs.AbsResource, 0, len(depMap))