diff --git a/terraform/graph_builder.go b/terraform/graph_builder.go index ca99667016..7963bcbf4f 100644 --- a/terraform/graph_builder.go +++ b/terraform/graph_builder.go @@ -105,9 +105,8 @@ func (b *BuiltinGraphBuilder) Steps(path []string) []GraphTransformer { // Create all our resources from the configuration and state &ConfigTransformer{Module: b.Root}, &OrphanTransformer{ - State: b.State, - Module: b.Root, - Targeting: len(b.Targets) > 0, + State: b.State, + Module: b.Root, }, // Output-related transformations diff --git a/terraform/graph_config_node_resource.go b/terraform/graph_config_node_resource.go index 2bf0e4568a..9fc696c2a3 100644 --- a/terraform/graph_config_node_resource.go +++ b/terraform/graph_config_node_resource.go @@ -163,9 +163,9 @@ func (n *GraphNodeConfigResource) DynamicExpand(ctx EvalContext) (*Graph, error) // expand orphans, which have all the same semantics in a destroy // as a primary. steps = append(steps, &OrphanTransformer{ - State: state, - View: n.Resource.Id(), - Targeting: len(n.Targets) > 0, + State: state, + View: n.Resource.Id(), + Targets: n.Targets, }) steps = append(steps, &DeposedTransformer{ diff --git a/terraform/transform_orphan.go b/terraform/transform_orphan.go index 45ea050ba3..13e8fbf941 100644 --- a/terraform/transform_orphan.go +++ b/terraform/transform_orphan.go @@ -2,7 +2,7 @@ package terraform import ( "fmt" - "log" + "strings" "github.com/hashicorp/terraform/config" "github.com/hashicorp/terraform/config/module" @@ -29,7 +29,7 @@ type OrphanTransformer struct { // Targets are user-specified resources to target. We need to be aware of // these so we don't improperly identify orphans when they've just been // filtered out of the graph via targeting. - Targeting bool + Targets []ResourceAddress // View, if non-nil will set a view on the module state. View string @@ -41,13 +41,6 @@ func (t *OrphanTransformer) Transform(g *Graph) error { return nil } - if t.Targeting { - log.Printf("Skipping orphan transformer because we have targets.") - // If we are in a run where we are targeting nodes, we won't process - // orphans for this run. - return nil - } - // Build up all our state representatives resourceRep := make(map[string]struct{}) for _, v := range g.Vertices() { @@ -74,8 +67,24 @@ func (t *OrphanTransformer) Transform(g *Graph) error { state = state.View(t.View) } - // Go over each resource orphan and add it to the graph. resourceOrphans := state.Orphans(config) + if len(t.Targets) > 0 { + var targetedOrphans []string + for _, o := range resourceOrphans { + targeted := false + for _, t := range t.Targets { + prefix := fmt.Sprintf("%s.%s.%d", t.Type, t.Name, t.Index) + if strings.HasPrefix(o, prefix) { + targeted = true + } + } + if targeted { + targetedOrphans = append(targetedOrphans, o) + } + } + resourceOrphans = targetedOrphans + } + resourceVertexes = make([]dag.Vertex, len(resourceOrphans)) for i, k := range resourceOrphans { // If this orphan is represented by some other node somehow, @@ -173,6 +182,10 @@ type graphNodeOrphanResource struct { dependentOn []string } +func (n *graphNodeOrphanResource) ResourceAddress() *ResourceAddress { + return n.ResourceAddress() +} + func (n *graphNodeOrphanResource) DependableName() []string { return []string{n.dependableName()} }