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  }