github.com/r3labs/terraform@v0.8.4/terraform/graph_builder_apply.go (about)

     1  package terraform
     2  
     3  import (
     4  	"github.com/hashicorp/terraform/config/module"
     5  	"github.com/hashicorp/terraform/dag"
     6  )
     7  
     8  // ApplyGraphBuilder implements GraphBuilder and is responsible for building
     9  // a graph for applying a Terraform diff.
    10  //
    11  // Because the graph is built from the diff (vs. the config or state),
    12  // this helps ensure that the apply-time graph doesn't modify any resources
    13  // that aren't explicitly in the diff. There are other scenarios where the
    14  // diff can be deviated, so this is just one layer of protection.
    15  type ApplyGraphBuilder struct {
    16  	// Module is the root module for the graph to build.
    17  	Module *module.Tree
    18  
    19  	// Diff is the diff to apply.
    20  	Diff *Diff
    21  
    22  	// State is the current state
    23  	State *State
    24  
    25  	// Providers is the list of providers supported.
    26  	Providers []string
    27  
    28  	// Provisioners is the list of provisioners supported.
    29  	Provisioners []string
    30  
    31  	// DisableReduce, if true, will not reduce the graph. Great for testing.
    32  	DisableReduce bool
    33  
    34  	// Destroy, if true, represents a pure destroy operation
    35  	Destroy bool
    36  
    37  	// Validate will do structural validation of the graph.
    38  	Validate bool
    39  }
    40  
    41  // See GraphBuilder
    42  func (b *ApplyGraphBuilder) Build(path []string) (*Graph, error) {
    43  	return (&BasicGraphBuilder{
    44  		Steps:    b.Steps(),
    45  		Validate: b.Validate,
    46  		Name:     "ApplyGraphBuilder",
    47  	}).Build(path)
    48  }
    49  
    50  // See GraphBuilder
    51  func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
    52  	// Custom factory for creating providers.
    53  	concreteProvider := func(a *NodeAbstractProvider) dag.Vertex {
    54  		return &NodeApplyableProvider{
    55  			NodeAbstractProvider: a,
    56  		}
    57  	}
    58  
    59  	concreteResource := func(a *NodeAbstractResource) dag.Vertex {
    60  		return &NodeApplyableResource{
    61  			NodeAbstractResource: a,
    62  		}
    63  	}
    64  
    65  	steps := []GraphTransformer{
    66  		// Creates all the nodes represented in the diff.
    67  		&DiffTransformer{
    68  			Concrete: concreteResource,
    69  
    70  			Diff:   b.Diff,
    71  			Module: b.Module,
    72  			State:  b.State,
    73  		},
    74  
    75  		// Create orphan output nodes
    76  		&OrphanOutputTransformer{Module: b.Module, State: b.State},
    77  
    78  		// Attach the configuration to any resources
    79  		&AttachResourceConfigTransformer{Module: b.Module},
    80  
    81  		// Attach the state
    82  		&AttachStateTransformer{State: b.State},
    83  
    84  		// Create all the providers
    85  		&MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider},
    86  		&ProviderTransformer{},
    87  		&DisableProviderTransformer{},
    88  		&ParentProviderTransformer{},
    89  		&AttachProviderConfigTransformer{Module: b.Module},
    90  
    91  		// Destruction ordering
    92  		&DestroyEdgeTransformer{Module: b.Module, State: b.State},
    93  		GraphTransformIf(
    94  			func() bool { return !b.Destroy },
    95  			&CBDEdgeTransformer{Module: b.Module, State: b.State},
    96  		),
    97  
    98  		// Provisioner-related transformations
    99  		GraphTransformIf(
   100  			func() bool { return !b.Destroy },
   101  			GraphTransformMulti(
   102  				&MissingProvisionerTransformer{Provisioners: b.Provisioners},
   103  				&ProvisionerTransformer{},
   104  			),
   105  		),
   106  
   107  		// Add root variables
   108  		&RootVariableTransformer{Module: b.Module},
   109  
   110  		// Add the outputs
   111  		&OutputTransformer{Module: b.Module},
   112  
   113  		// Add module variables
   114  		&ModuleVariableTransformer{Module: b.Module},
   115  
   116  		// Connect references so ordering is correct
   117  		&ReferenceTransformer{},
   118  
   119  		// Add the node to fix the state count boundaries
   120  		&CountBoundaryTransformer{},
   121  
   122  		// Single root
   123  		&RootTransformer{},
   124  	}
   125  
   126  	if !b.DisableReduce {
   127  		// Perform the transitive reduction to make our graph a bit
   128  		// more sane if possible (it usually is possible).
   129  		steps = append(steps, &TransitiveReductionTransformer{})
   130  	}
   131  
   132  	return steps
   133  }