github.com/hashicorp/terraform-plugin-sdk@v1.17.2/terraform/transform_orphan_output.go (about) 1 package terraform 2 3 import ( 4 "log" 5 6 "github.com/hashicorp/terraform-plugin-sdk/internal/addrs" 7 "github.com/hashicorp/terraform-plugin-sdk/internal/configs" 8 "github.com/hashicorp/terraform-plugin-sdk/internal/states" 9 ) 10 11 // OrphanOutputTransformer finds the outputs that aren't present 12 // in the given config that are in the state and adds them to the graph 13 // for deletion. 14 type OrphanOutputTransformer struct { 15 Config *configs.Config // Root of config tree 16 State *states.State // State is the root state 17 } 18 19 func (t *OrphanOutputTransformer) Transform(g *Graph) error { 20 if t.State == nil { 21 log.Printf("[DEBUG] No state, no orphan outputs") 22 return nil 23 } 24 25 for _, ms := range t.State.Modules { 26 if err := t.transform(g, ms); err != nil { 27 return err 28 } 29 } 30 return nil 31 } 32 33 func (t *OrphanOutputTransformer) transform(g *Graph, ms *states.Module) error { 34 if ms == nil { 35 return nil 36 } 37 38 moduleAddr := ms.Addr 39 40 // Get the config for this path, which is nil if the entire module has been 41 // removed. 42 var outputs map[string]*configs.Output 43 if c := t.Config.DescendentForInstance(moduleAddr); c != nil { 44 outputs = c.Module.Outputs 45 } 46 47 // An output is "orphaned" if it's present in the state but not declared 48 // in the configuration. 49 for name := range ms.OutputValues { 50 if _, exists := outputs[name]; exists { 51 continue 52 } 53 54 g.Add(&NodeOutputOrphan{ 55 Addr: addrs.OutputValue{Name: name}.Absolute(moduleAddr), 56 }) 57 } 58 59 return nil 60 }