core: Don't create self-references in state
Since StateReferences was implemented on NodeAbstractResource rather than NodeAbstractResourceInstance it wasn't properly detecting references to the same instance as self-references. Now that we are using "seen" to filter out duplicates we can also simplify how we handle these self-references by just pretending we saw them before we even start the loop. This change is confirmed by TestContext2Apply_provisionerMultiSelfRefSingle
This commit is contained in:
parent
9afb0c6c0c
commit
77e50894d5
|
@ -270,7 +270,7 @@ func dottedInstanceAddr(tr addrs.ResourceInstance) string {
|
|||
|
||||
// StateReferences returns the dependencies to put into the state for
|
||||
// this resource.
|
||||
func (n *NodeAbstractResource) StateReferences() []addrs.Referenceable {
|
||||
func (n *NodeAbstractResourceInstance) StateReferences() []addrs.Referenceable {
|
||||
selfAddrs := n.ReferenceableAddrs()
|
||||
|
||||
// Since we don't include the source location references in our
|
||||
|
@ -279,6 +279,18 @@ func (n *NodeAbstractResource) StateReferences() []addrs.Referenceable {
|
|||
// that additional context.
|
||||
seen := map[string]struct{}{}
|
||||
|
||||
// Pretend that we've already "seen" all of our own addresses so that we
|
||||
// won't record self-references in the state. This can arise if, for
|
||||
// example, a provisioner for a resource refers to the resource itself,
|
||||
// which is valid (since provisioners always run after apply) but should
|
||||
// not create an explicit dependency edge.
|
||||
for _, selfAddr := range selfAddrs {
|
||||
seen[selfAddr.String()] = struct{}{}
|
||||
if riAddr, ok := selfAddr.(addrs.ResourceInstance); ok {
|
||||
seen[riAddr.ContainingResource().String()] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
depsRaw := n.References()
|
||||
deps := make([]addrs.Referenceable, 0, len(depsRaw))
|
||||
for _, d := range depsRaw {
|
||||
|
@ -300,17 +312,7 @@ func (n *NodeAbstractResource) StateReferences() []addrs.Referenceable {
|
|||
case addrs.ResourceInstance:
|
||||
deps = append(deps, tr)
|
||||
case addrs.Resource:
|
||||
depStr := tr.String()
|
||||
selfRef := false
|
||||
for _, selfAddr := range selfAddrs {
|
||||
if selfAddr.String() == depStr {
|
||||
selfRef = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !selfRef { // Don't create self-references
|
||||
deps = append(deps, tr)
|
||||
}
|
||||
deps = append(deps, tr)
|
||||
case addrs.ModuleCallInstance:
|
||||
deps = append(deps, tr)
|
||||
default:
|
||||
|
|
|
@ -726,7 +726,7 @@ aws_instance.foo.1:
|
|||
type = aws_instance
|
||||
|
||||
Dependencies:
|
||||
aws_instance.foo.0
|
||||
aws_instance.foo[0]
|
||||
aws_instance.foo.2:
|
||||
ID = foo
|
||||
provider = provider.aws
|
||||
|
@ -734,7 +734,7 @@ aws_instance.foo.2:
|
|||
type = aws_instance
|
||||
|
||||
Dependencies:
|
||||
aws_instance.foo.0
|
||||
aws_instance.foo[0]
|
||||
`
|
||||
|
||||
const testTerraformApplyProvisionerDiffStr = `
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
resource "aws_instance" "foo" {
|
||||
count = 3
|
||||
foo = "number ${count.index}"
|
||||
count = 3
|
||||
foo = "number ${count.index}"
|
||||
|
||||
provisioner "shell" {
|
||||
command = "${aws_instance.foo.0.foo}"
|
||||
order = "${count.index}"
|
||||
}
|
||||
provisioner "shell" {
|
||||
command = aws_instance.foo[0].foo
|
||||
order = count.index
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue