terraform: only include variables in graph if count of a resource

depends
This commit is contained in:
Mitchell Hashimoto 2015-05-07 10:50:56 -07:00
parent 6b2e0b938d
commit 6752ccfe10
4 changed files with 38 additions and 11 deletions

View File

@ -62,7 +62,7 @@ func (n *GraphNodeConfigOutput) Proxy() bool {
}
// GraphNodeDestroyEdgeInclude impl.
func (n *GraphNodeConfigOutput) DestroyEdgeInclude(bool) bool {
func (n *GraphNodeConfigOutput) DestroyEdgeInclude(dag.Vertex) bool {
return false
}

View File

@ -9,6 +9,12 @@ import (
"github.com/hashicorp/terraform/dot"
)
// GraphNodeCountDependent is implemented by resources for giving only
// the dependencies they have from the "count" field.
type GraphNodeCountDependent interface {
CountDependentOn() []string
}
// GraphNodeConfigResource represents a resource within the config graph.
type GraphNodeConfigResource struct {
Resource *config.Resource
@ -31,6 +37,18 @@ func (n *GraphNodeConfigResource) DependableName() []string {
return []string{n.Resource.Id()}
}
// GraphNodeCountDependent impl.
func (n *GraphNodeConfigResource) CountDependentOn() []string {
result := make([]string, 0, len(n.Resource.RawCount.Variables))
for _, v := range n.Resource.RawCount.Variables {
if vn := varNameForVar(v); vn != "" {
result = append(result, vn)
}
}
return result
}
// GraphNodeDependent impl.
func (n *GraphNodeConfigResource) DependentOn() []string {
result := make([]string, len(n.Resource.DependsOn),

View File

@ -56,14 +56,23 @@ func (n *GraphNodeConfigVariable) VariableName() string {
}
// GraphNodeDestroyEdgeInclude impl.
func (n *GraphNodeConfigVariable) DestroyEdgeInclude(full bool) bool {
// Don't include variables as dependencies in destroy nodes.
// Destroy nodes don't interpolate anyways and this has a possibility
// to create cycles. See GH-1835
//
// We include the variable on non-full destroys because it might
// be used for count interpolation.
return !full
func (n *GraphNodeConfigVariable) DestroyEdgeInclude(v dag.Vertex) bool {
// Only include this variable in a destroy edge if the source vertex
// "v" has a count dependency on this variable.
cv, ok := v.(GraphNodeCountDependent)
if !ok {
return false
}
for _, d := range cv.CountDependentOn() {
for _, d2 := range n.DependableName() {
if d == d2 {
return true
}
}
}
return false
}
// GraphNodeProxy impl.

View File

@ -49,7 +49,7 @@ type GraphNodeDestroyPrunable interface {
// as an edge within the destroy graph. This is usually done because it
// might cause unnecessary cycles.
type GraphNodeDestroyEdgeInclude interface {
DestroyEdgeInclude(bool) bool
DestroyEdgeInclude(dag.Vertex) bool
}
// DestroyTransformer is a GraphTransformer that creates the destruction
@ -114,7 +114,7 @@ func (t *DestroyTransformer) transform(
// If this thing specifically requests to not be depended on
// by destroy nodes, then don't.
if i, ok := edgeRaw.(GraphNodeDestroyEdgeInclude); ok &&
!i.DestroyEdgeInclude(t.FullDestroy) {
!i.DestroyEdgeInclude(v) {
continue
}