github.com/adamar/terraform@v0.2.2-0.20141016210445-2e703afdad0e/terraform/graph.go (about)

     1  package terraform
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"log"
     7  	"sort"
     8  	"strings"
     9  
    10  	"github.com/hashicorp/terraform/config"
    11  	"github.com/hashicorp/terraform/config/module"
    12  	"github.com/hashicorp/terraform/depgraph"
    13  	"github.com/hashicorp/terraform/helper/multierror"
    14  )
    15  
    16  // GraphOpts are options used to create the resource graph that Terraform
    17  // walks to make changes to infrastructure.
    18  //
    19  // Depending on what options are set, the resulting graph will come in
    20  // varying degrees of completeness.
    21  type GraphOpts struct {
    22  	// Config is the configuration from which to build the basic graph.
    23  	// This is the only required item.
    24  	//Config *config.Config
    25  
    26  	// Module is the relative root of a module tree for this graph. This
    27  	// is the only required item. This should always be the absolute root
    28  	// of the tree. ModulePath below should be used to constrain the depth.
    29  	//
    30  	// ModulePath specifies the place in the tree where Module exists.
    31  	// This is used for State lookups.
    32  	Module     *module.Tree
    33  	ModulePath []string
    34  
    35  	// Diff of changes that will be applied to the given state. This will
    36  	// associate a ResourceDiff with applicable resources. Additionally,
    37  	// new resource nodes representing resource destruction may be inserted
    38  	// into the graph.
    39  	Diff *Diff
    40  
    41  	// State, if present, will make the ResourceState available on each
    42  	// resource node. Additionally, any orphans will be added automatically
    43  	// to the graph.
    44  	//
    45  	// Note: the state will be modified so it is initialized with basic
    46  	// empty states for all modules/resources in this graph. If you call prune
    47  	// later, these will be removed, but the graph adds important metadata.
    48  	State *State
    49  
    50  	// Providers is a mapping of prefixes to a resource provider. If given,
    51  	// resource providers will be found, initialized, and associated to the
    52  	// resources in the graph.
    53  	//
    54  	// This will also potentially insert new nodes into the graph for
    55  	// the configuration of resource providers.
    56  	Providers map[string]ResourceProviderFactory
    57  
    58  	// Provisioners is a mapping of names to a resource provisioner.
    59  	// These must be provided to support resource provisioners.
    60  	Provisioners map[string]ResourceProvisionerFactory
    61  
    62  	// parent specifies the parent graph if there is one. This should not be
    63  	// set manually.
    64  	parent *depgraph.Graph
    65  }
    66  
    67  // GraphRootNode is the name of the root node in the Terraform resource
    68  // graph. This node is just a placemarker and has no associated functionality.
    69  const GraphRootNode = "root"
    70  
    71  // GraphMeta is the metadata attached to the graph itself.
    72  type GraphMeta struct {
    73  	// ModulePath is the path of the module that this graph represents.
    74  	ModulePath []string
    75  }
    76  
    77  // GraphNodeModule is a node type in the graph that represents a module
    78  // that will be created/managed.
    79  type GraphNodeModule struct {
    80  	Config *config.Module
    81  	Path   []string
    82  	Graph  *depgraph.Graph
    83  }
    84  
    85  // GraphNodeResource is a node type in the graph that represents a resource
    86  // that will be created or managed. Unlike the GraphNodeResourceMeta node,
    87  // this represents a _single_, _resource_ to be managed, not a set of resources
    88  // or a component of a resource.
    89  type GraphNodeResource struct {
    90  	Index                int
    91  	Config               *config.Resource
    92  	Resource             *Resource
    93  	ResourceProviderNode string
    94  
    95  	// All the fields below are related to expansion. These are set by
    96  	// the graph but aren't useful individually.
    97  	ExpandMode ResourceExpandMode
    98  	Diff       *ModuleDiff
    99  	State      *ModuleState
   100  }
   101  
   102  // GraphNodeResourceProvider is a node type in the graph that represents
   103  // the configuration for a resource provider.
   104  type GraphNodeResourceProvider struct {
   105  	ID       string
   106  	Provider *graphSharedProvider
   107  }
   108  
   109  // graphSharedProvider is a structure that stores a configuration
   110  // with initialized providers and might be shared across different
   111  // graphs in order to have only one instance of a provider.
   112  type graphSharedProvider struct {
   113  	Config       *config.ProviderConfig
   114  	Providers    map[string]ResourceProvider
   115  	ProviderKeys []string
   116  	Parent       *graphSharedProvider
   117  
   118  	overrideConfig map[string]map[string]interface{}
   119  	parentNoun     *depgraph.Noun
   120  }
   121  
   122  // ResourceExpandMode specifies the expand behavior of the GraphNodeResource
   123  // node.
   124  type ResourceExpandMode byte
   125  
   126  const (
   127  	ResourceExpandNone ResourceExpandMode = iota
   128  	ResourceExpandApply
   129  	ResourceExpandDestroy
   130  )
   131  
   132  // Graph builds a dependency graph of all the resources for infrastructure
   133  // change.
   134  //
   135  // This dependency graph shows the correct order that any resources need
   136  // to be operated on.
   137  //
   138  // The Meta field of a graph Noun can contain one of the follow types. A
   139  // description is next to each type to explain what it is.
   140  //
   141  //   *GraphNodeResource - A resource. See the documentation of this
   142  //     struct for more details.
   143  //   *GraphNodeResourceProvider - A resource provider that needs to be
   144  //     configured at this point.
   145  //
   146  func Graph(opts *GraphOpts) (*depgraph.Graph, error) {
   147  	if opts.Module == nil {
   148  		return nil, errors.New("Module is required for Graph")
   149  	}
   150  	if opts.ModulePath == nil {
   151  		opts.ModulePath = rootModulePath
   152  	}
   153  	if !opts.Module.Loaded() {
   154  		return nil, errors.New("Module must be loaded")
   155  	}
   156  
   157  	// Get the correct module in the tree that we're looking for.
   158  	currentModule := opts.Module
   159  	for _, n := range opts.ModulePath[1:] {
   160  		children := currentModule.Children()
   161  		currentModule = children[n]
   162  	}
   163  
   164  	var conf *config.Config
   165  	if currentModule != nil {
   166  		conf = currentModule.Config()
   167  	} else {
   168  		conf = new(config.Config)
   169  	}
   170  
   171  	// Get the state and diff of the module that we're working with.
   172  	var modDiff *ModuleDiff
   173  	var modState *ModuleState
   174  	if opts.Diff != nil {
   175  		modDiff = opts.Diff.ModuleByPath(opts.ModulePath)
   176  	}
   177  	if opts.State != nil {
   178  		modState = opts.State.ModuleByPath(opts.ModulePath)
   179  	}
   180  
   181  	log.Printf("[DEBUG] Creating graph for path: %v", opts.ModulePath)
   182  
   183  	g := new(depgraph.Graph)
   184  	g.Meta = &GraphMeta{
   185  		ModulePath: opts.ModulePath,
   186  	}
   187  
   188  	// First, build the initial resource graph. This only has the resources
   189  	// and no dependencies. This only adds resources that are in the config
   190  	// and not "orphans" (that are in the state, but not in the config).
   191  	graphAddConfigResources(g, conf, modState)
   192  
   193  	if modState != nil {
   194  		// Next, add the state orphans if we have any
   195  		graphAddOrphans(g, conf, modState)
   196  
   197  		// Add tainted resources if we have any.
   198  		graphAddTainted(g, modState)
   199  	}
   200  
   201  	// Create the resource provider nodes for explicitly configured
   202  	// providers within our graph.
   203  	graphAddConfigProviderConfigs(g, conf)
   204  
   205  	if opts.parent != nil {
   206  		// Add/merge the provider configurations from the parent so that
   207  		// we properly "inherit" providers.
   208  		graphAddParentProviderConfigs(g, opts.parent)
   209  	}
   210  
   211  	// First pass matching resources to providers. This will allow us to
   212  	// determine what providers are missing.
   213  	graphMapResourceProviderId(g)
   214  
   215  	if len(opts.Providers) > 0 {
   216  		// Add missing providers from the mapping.
   217  		if err := graphAddMissingResourceProviders(g, opts.Providers); err != nil {
   218  			return nil, err
   219  		}
   220  
   221  		// Initialize all the providers
   222  		if err := graphInitResourceProviders(g, opts.Providers); err != nil {
   223  			return nil, err
   224  		}
   225  
   226  		// Map the providers to resources
   227  		if err := graphMapResourceProviders(g); err != nil {
   228  			return nil, err
   229  		}
   230  	}
   231  
   232  	// Add the modules that are in the configuration.
   233  	if err := graphAddConfigModules(g, conf, opts); err != nil {
   234  		return nil, err
   235  	}
   236  
   237  	if opts.State != nil {
   238  		// Add module orphans if we have any of those
   239  		if ms := opts.State.Children(opts.ModulePath); len(ms) > 0 {
   240  			if err := graphAddModuleOrphans(g, conf, ms, opts); err != nil {
   241  				return nil, err
   242  			}
   243  		}
   244  	}
   245  
   246  	// Add the orphan dependencies
   247  	graphAddOrphanDeps(g, modState)
   248  
   249  	// Add the provider dependencies
   250  	graphAddResourceProviderDeps(g)
   251  
   252  	// Now, prune the providers that we aren't using.
   253  	graphPruneResourceProviders(g)
   254  
   255  	// Add explicit dependsOn dependencies to the graph
   256  	graphAddExplicitDeps(g)
   257  
   258  	// Setup the provisioners. These may have variable dependencies,
   259  	// and must be done before dependency setup
   260  	if err := graphMapResourceProvisioners(g, opts.Provisioners); err != nil {
   261  		return nil, err
   262  	}
   263  
   264  	// Add all the variable dependencies
   265  	graphAddVariableDeps(g)
   266  
   267  	// Build the root so that we have a single valid root
   268  	graphAddRoot(g)
   269  
   270  	// If we have a diff, then make sure to add that in
   271  	if modDiff != nil {
   272  		if err := graphAddDiff(g, modDiff); err != nil {
   273  			return nil, err
   274  		}
   275  	}
   276  
   277  	// Encode the dependencies
   278  	graphEncodeDependencies(g)
   279  
   280  	// Validate
   281  	if err := g.Validate(); err != nil {
   282  		return nil, err
   283  	}
   284  
   285  	log.Printf(
   286  		"[DEBUG] Graph %v created and valid. %d nouns.",
   287  		opts.ModulePath,
   288  		len(g.Nouns))
   289  
   290  	return g, nil
   291  }
   292  
   293  // graphEncodeDependencies is used to initialize a State with a ResourceState
   294  // for every resource.
   295  //
   296  // This method is very important to call because it will properly setup
   297  // the ResourceState dependency information with data from the graph. This
   298  // allows orphaned resources to be destroyed in the proper order.
   299  func graphEncodeDependencies(g *depgraph.Graph) {
   300  	for _, n := range g.Nouns {
   301  		// Ignore any non-resource nodes
   302  		rn, ok := n.Meta.(*GraphNodeResource)
   303  		if !ok {
   304  			continue
   305  		}
   306  		r := rn.Resource
   307  
   308  		// If we are using create-before-destroy, there
   309  		// are some special depedencies injected on the
   310  		// deposed node that would cause a circular depedency
   311  		// chain if persisted. We must only handle the new node,
   312  		// node the deposed node.
   313  		if r.Flags&FlagDeposed != 0 {
   314  			continue
   315  		}
   316  
   317  		// Update the dependencies
   318  		var inject []string
   319  		for _, dep := range n.Deps {
   320  			switch target := dep.Target.Meta.(type) {
   321  			case *GraphNodeModule:
   322  				inject = append(inject, dep.Target.Name)
   323  
   324  			case *GraphNodeResource:
   325  				if target.Resource.Id == r.Id {
   326  					continue
   327  				}
   328  				inject = append(inject, target.Resource.Id)
   329  
   330  			case *GraphNodeResourceProvider:
   331  				// Do nothing
   332  
   333  			default:
   334  				panic(fmt.Sprintf("Unknown graph node: %#v", dep.Target))
   335  			}
   336  		}
   337  
   338  		// Update the dependencies
   339  		r.Dependencies = inject
   340  	}
   341  }
   342  
   343  // graphAddConfigModules adds the modules from a configuration structure
   344  // into the graph, expanding each to their own sub-graph.
   345  func graphAddConfigModules(
   346  	g *depgraph.Graph,
   347  	c *config.Config,
   348  	opts *GraphOpts) error {
   349  	// Just short-circuit the whole thing if we don't have modules
   350  	if len(c.Modules) == 0 {
   351  		return nil
   352  	}
   353  
   354  	// Build the list of nouns to add to the graph
   355  	nounsList := make([]*depgraph.Noun, 0, len(c.Modules))
   356  	for _, m := range c.Modules {
   357  		if n, err := graphModuleNoun(m.Name, m, g, opts); err != nil {
   358  			return err
   359  		} else {
   360  			nounsList = append(nounsList, n)
   361  		}
   362  	}
   363  
   364  	g.Nouns = append(g.Nouns, nounsList...)
   365  	return nil
   366  }
   367  
   368  // configGraph turns a configuration structure into a dependency graph.
   369  func graphAddConfigResources(
   370  	g *depgraph.Graph, c *config.Config, mod *ModuleState) {
   371  	meta := g.Meta.(*GraphMeta)
   372  
   373  	// This tracks all the resource nouns
   374  	nounsList := make([]*depgraph.Noun, len(c.Resources))
   375  	for i, r := range c.Resources {
   376  		name := r.Id()
   377  
   378  		// Build the noun
   379  		nounsList[i] = &depgraph.Noun{
   380  			Name: name,
   381  			Meta: &GraphNodeResource{
   382  				Index:  -1,
   383  				Config: r,
   384  				Resource: &Resource{
   385  					Id: name,
   386  					Info: &InstanceInfo{
   387  						Id:         name,
   388  						ModulePath: meta.ModulePath,
   389  						Type:       r.Type,
   390  					},
   391  				},
   392  				State:      mod.View(name),
   393  				ExpandMode: ResourceExpandApply,
   394  			},
   395  		}
   396  
   397  		/*
   398  			TODO: probably did something important, bring it back somehow
   399  			resourceNouns := make([]*depgraph.Noun, r.Count)
   400  			for i := 0; i < r.Count; i++ {
   401  				name := r.Id()
   402  				index := -1
   403  
   404  				// If we have a count that is more than one, then make sure
   405  				// we suffix with the number of the resource that this is.
   406  				if r.Count > 1 {
   407  					name = fmt.Sprintf("%s.%d", name, i)
   408  					index = i
   409  				}
   410  
   411  				var state *ResourceState
   412  				if mod != nil {
   413  					// Lookup the resource state
   414  					state = mod.Resources[name]
   415  					if state == nil {
   416  						if r.Count == 1 {
   417  							// If the count is one, check the state for ".0"
   418  							// appended, which might exist if we go from
   419  							// count > 1 to count == 1.
   420  							state = mod.Resources[r.Id()+".0"]
   421  						} else if i == 0 {
   422  							// If count is greater than one, check for state
   423  							// with just the ID, which might exist if we go
   424  							// from count == 1 to count > 1
   425  							state = mod.Resources[r.Id()]
   426  						}
   427  
   428  						// TODO(mitchellh): If one of the above works, delete
   429  						// the old style and just copy it to the new style.
   430  					}
   431  				}
   432  
   433  				if state == nil {
   434  					state = &ResourceState{
   435  						Type: r.Type,
   436  					}
   437  				}
   438  
   439  				flags := FlagPrimary
   440  				if len(state.Tainted) > 0 {
   441  					flags |= FlagHasTainted
   442  				}
   443  
   444  				resourceNouns[i] = &depgraph.Noun{
   445  					Name: name,
   446  					Meta: &GraphNodeResource{
   447  						Index:  index,
   448  						Config: r,
   449  						Resource: &Resource{
   450  							Id: name,
   451  							Info: &InstanceInfo{
   452  								Id:         name,
   453  								ModulePath: meta.ModulePath,
   454  								Type:       r.Type,
   455  							},
   456  							State:  state.Primary,
   457  							Config: NewResourceConfig(r.RawConfig),
   458  							Flags:  flags,
   459  						},
   460  					},
   461  				}
   462  			}
   463  
   464  			// If we have more than one, then create a meta node to track
   465  			// the resources.
   466  			if r.Count > 1 {
   467  				metaNoun := &depgraph.Noun{
   468  					Name: r.Id(),
   469  					Meta: &GraphNodeResourceMeta{
   470  						ID:    r.Id(),
   471  						Name:  r.Name,
   472  						Type:  r.Type,
   473  						Count: r.Count,
   474  					},
   475  				}
   476  
   477  				// Create the dependencies on this noun
   478  				for _, n := range resourceNouns {
   479  					metaNoun.Deps = append(metaNoun.Deps, &depgraph.Dependency{
   480  						Name:   n.Name,
   481  						Source: metaNoun,
   482  						Target: n,
   483  					})
   484  				}
   485  
   486  				// Assign it to the map so that we have it
   487  				nouns[metaNoun.Name] = metaNoun
   488  			}
   489  
   490  			for _, n := range resourceNouns {
   491  				nouns[n.Name] = n
   492  			}
   493  		*/
   494  	}
   495  
   496  	g.Name = "terraform"
   497  	g.Nouns = append(g.Nouns, nounsList...)
   498  }
   499  
   500  // graphAddDiff takes an already-built graph of resources and adds the
   501  // diffs to the resource nodes themselves.
   502  //
   503  // This may also introduces new graph elements. If there are diffs that
   504  // require a destroy, new elements may be introduced since destroy order
   505  // is different than create order. For example, destroying a VPC requires
   506  // destroying the VPC's subnets first, whereas creating a VPC requires
   507  // doing it before the subnets are created. This function handles inserting
   508  // these nodes for you.
   509  func graphAddDiff(g *depgraph.Graph, d *ModuleDiff) error {
   510  	var nlist []*depgraph.Noun
   511  	injected := make(map[*depgraph.Dependency]struct{})
   512  	for _, n := range g.Nouns {
   513  		rn, ok := n.Meta.(*GraphNodeResource)
   514  		if !ok {
   515  			continue
   516  		}
   517  		if rn.Resource.Flags&FlagTainted != 0 {
   518  			continue
   519  		}
   520  
   521  		change := false
   522  		destroy := false
   523  		diffs := d.Instances(rn.Resource.Id)
   524  		if len(diffs) == 0 {
   525  			continue
   526  		}
   527  		for _, d := range diffs {
   528  			if d.Destroy {
   529  				destroy = true
   530  			}
   531  
   532  			if len(d.Attributes) > 0 {
   533  				change = true
   534  			}
   535  		}
   536  
   537  		// If we're expanding, save the diff so we can add it on later
   538  		if rn.ExpandMode > ResourceExpandNone {
   539  			rn.Diff = d
   540  		}
   541  
   542  		var rd *InstanceDiff
   543  		if rn.ExpandMode == ResourceExpandNone {
   544  			rd = diffs[0]
   545  		}
   546  
   547  		if destroy {
   548  			// If we're destroying, we create a new destroy node with
   549  			// the proper dependencies. Perform a dirty copy operation.
   550  			newNode := new(GraphNodeResource)
   551  			*newNode = *rn
   552  			newNode.Resource = new(Resource)
   553  			*newNode.Resource = *rn.Resource
   554  
   555  			// Make the diff _just_ the destroy.
   556  			newNode.Resource.Diff = &InstanceDiff{Destroy: true}
   557  
   558  			// Make sure ExpandDestroy is set if Expand
   559  			if newNode.ExpandMode == ResourceExpandApply {
   560  				newNode.ExpandMode = ResourceExpandDestroy
   561  			}
   562  
   563  			// Create the new node
   564  			newN := &depgraph.Noun{
   565  				Name: fmt.Sprintf("%s (destroy)", newNode.Resource.Id),
   566  				Meta: newNode,
   567  			}
   568  			newN.Deps = make([]*depgraph.Dependency, len(n.Deps))
   569  
   570  			// Copy all the dependencies and do a fixup later
   571  			copy(newN.Deps, n.Deps)
   572  
   573  			// Append it to the list so we handle it later
   574  			nlist = append(nlist, newN)
   575  
   576  			if rd != nil {
   577  				// Mark the old diff to not destroy since we handle that in
   578  				// the dedicated node.
   579  				newDiff := new(InstanceDiff)
   580  				*newDiff = *rd
   581  				newDiff.Destroy = false
   582  				rd = newDiff
   583  			}
   584  
   585  			// The dependency ordering depends on if the CreateBeforeDestroy
   586  			// flag is enabled. If so, we must create the replacement first,
   587  			// and then destroy the old instance.
   588  			if rn.Config != nil && rn.Config.Lifecycle.CreateBeforeDestroy && change {
   589  				dep := &depgraph.Dependency{
   590  					Name:   n.Name,
   591  					Source: newN,
   592  					Target: n,
   593  				}
   594  
   595  				// Add the old noun to the new noun dependencies so that
   596  				// the create happens before the destroy.
   597  				newN.Deps = append(newN.Deps, dep)
   598  
   599  				// Mark that this dependency has been injected so that
   600  				// we do not invert the direction below.
   601  				injected[dep] = struct{}{}
   602  
   603  				// Add a depedency from the root, since the create node
   604  				// does not depend on us
   605  				if g.Root != nil {
   606  					g.Root.Deps = append(g.Root.Deps, &depgraph.Dependency{
   607  						Name:   newN.Name,
   608  						Source: g.Root,
   609  						Target: newN,
   610  					})
   611  				}
   612  
   613  				// Set the ReplacePrimary flag on the new instance so that
   614  				// it will become the new primary, and Diposed flag on the
   615  				// existing instance so that it will step down
   616  				rn.Resource.Flags |= FlagReplacePrimary
   617  				newNode.Resource.Flags |= FlagDeposed
   618  
   619  				// This logic is not intuitive, but we need to make the
   620  				// destroy depend upon any resources that depend on the
   621  				// create. The reason is suppose you have a LB depend on
   622  				// a web server. You need the order to be create, update LB,
   623  				// destroy. Without this, the update LB and destroy can
   624  				// be executed in an arbitrary order (likely in parallel).
   625  				incoming := g.DependsOn(n)
   626  				for _, inc := range incoming {
   627  					// Ignore the root...
   628  					if inc == g.Root {
   629  						continue
   630  					}
   631  					dep := &depgraph.Dependency{
   632  						Name:   inc.Name,
   633  						Source: newN,
   634  						Target: inc,
   635  					}
   636  					injected[dep] = struct{}{}
   637  					newN.Deps = append(newN.Deps, dep)
   638  				}
   639  
   640  			} else {
   641  				dep := &depgraph.Dependency{
   642  					Name:   newN.Name,
   643  					Source: n,
   644  					Target: newN,
   645  				}
   646  
   647  				// Add the new noun to our dependencies so that
   648  				// the destroy happens before the apply.
   649  				n.Deps = append(n.Deps, dep)
   650  			}
   651  		}
   652  
   653  		rn.Resource.Diff = rd
   654  	}
   655  
   656  	// Go through each noun and make sure we calculate all the dependencies
   657  	// properly.
   658  	for _, n := range nlist {
   659  		deps := n.Deps
   660  		num := len(deps)
   661  		for i := 0; i < num; i++ {
   662  			dep := deps[i]
   663  
   664  			// Check if this dependency was just injected, otherwise
   665  			// we will incorrectly flip the depedency twice.
   666  			if _, ok := injected[dep]; ok {
   667  				continue
   668  			}
   669  
   670  			switch target := dep.Target.Meta.(type) {
   671  			case *GraphNodeResource:
   672  				// If the other node is also being deleted,
   673  				// we must be deleted first. E.g. if A -> B,
   674  				// then when we create, B is created first then A.
   675  				// On teardown, A is destroyed first, then B.
   676  				// Thus we must flip our depedency and instead inject
   677  				// it on B.
   678  				for _, n2 := range nlist {
   679  					rn2 := n2.Meta.(*GraphNodeResource)
   680  					if target.Resource.Id == rn2.Resource.Id {
   681  						newDep := &depgraph.Dependency{
   682  							Name:   n.Name,
   683  							Source: n2,
   684  							Target: n,
   685  						}
   686  						injected[newDep] = struct{}{}
   687  						n2.Deps = append(n2.Deps, newDep)
   688  						break
   689  					}
   690  				}
   691  
   692  				// Drop the dependency. We may have created
   693  				// an inverse depedency if the dependent resource
   694  				// is also being deleted, but this dependence is
   695  				// no longer required.
   696  				deps[i], deps[num-1] = deps[num-1], nil
   697  				num--
   698  				i--
   699  
   700  			case *GraphNodeModule:
   701  				// We invert any module dependencies so we're destroyed
   702  				// first, before any modules are applied.
   703  				newDep := &depgraph.Dependency{
   704  					Name:   n.Name,
   705  					Source: dep.Target,
   706  					Target: n,
   707  				}
   708  				dep.Target.Deps = append(dep.Target.Deps, newDep)
   709  
   710  				// Drop the dependency. We may have created
   711  				// an inverse depedency if the dependent resource
   712  				// is also being deleted, but this dependence is
   713  				// no longer required.
   714  				deps[i], deps[num-1] = deps[num-1], nil
   715  				num--
   716  				i--
   717  			case *GraphNodeResourceProvider:
   718  				// Keep these around, but fix up the source to be ourselves
   719  				// rather than the old node.
   720  				newDep := *dep
   721  				newDep.Source = n
   722  				deps[i] = &newDep
   723  			default:
   724  				panic(fmt.Errorf("Unhandled depedency type: %#v", dep.Target.Meta))
   725  			}
   726  		}
   727  		n.Deps = deps[:num]
   728  	}
   729  
   730  	// Add the nouns to the graph
   731  	g.Nouns = append(g.Nouns, nlist...)
   732  
   733  	return nil
   734  }
   735  
   736  // graphAddExplicitDeps adds the dependencies to the graph for the explicit
   737  // dependsOn configurations.
   738  func graphAddExplicitDeps(g *depgraph.Graph) {
   739  	depends := false
   740  
   741  	rs := make(map[string]*depgraph.Noun)
   742  	for _, n := range g.Nouns {
   743  		rn, ok := n.Meta.(*GraphNodeResource)
   744  		if !ok {
   745  			continue
   746  		}
   747  		if rn.Config == nil {
   748  			// Orphan. It can't be depended on or have depends (explicit)
   749  			// anyways.
   750  			continue
   751  		}
   752  
   753  		rs[rn.Resource.Id] = n
   754  		if rn.Config != nil && len(rn.Config.DependsOn) > 0 {
   755  			depends = true
   756  		}
   757  	}
   758  
   759  	// If we didn't have any dependsOn, just return
   760  	if !depends {
   761  		return
   762  	}
   763  
   764  	for _, n1 := range rs {
   765  		rn1 := n1.Meta.(*GraphNodeResource)
   766  		for _, d := range rn1.Config.DependsOn {
   767  			for _, n2 := range rs {
   768  				rn2 := n2.Meta.(*GraphNodeResource)
   769  				if rn2.Config.Id() != d {
   770  					continue
   771  				}
   772  
   773  				n1.Deps = append(n1.Deps, &depgraph.Dependency{
   774  					Name:   d,
   775  					Source: n1,
   776  					Target: n2,
   777  				})
   778  			}
   779  		}
   780  	}
   781  }
   782  
   783  // graphAddMissingResourceProviders adds GraphNodeResourceProvider nodes for
   784  // the resources that do not have an explicit resource provider specified
   785  // because no provider configuration was given.
   786  func graphAddMissingResourceProviders(
   787  	g *depgraph.Graph,
   788  	ps map[string]ResourceProviderFactory) error {
   789  	var errs []error
   790  
   791  	for _, n := range g.Nouns {
   792  		rn, ok := n.Meta.(*GraphNodeResource)
   793  		if !ok {
   794  			continue
   795  		}
   796  		if rn.ResourceProviderNode != "" {
   797  			continue
   798  		}
   799  
   800  		prefixes := matchingPrefixes(rn.Resource.Info.Type, ps)
   801  		if len(prefixes) == 0 {
   802  			errs = append(errs, fmt.Errorf(
   803  				"No matching provider for type: %s",
   804  				rn.Resource.Info.Type))
   805  			continue
   806  		}
   807  
   808  		// The resource provider ID is simply the shortest matching
   809  		// prefix, since that'll give us the most resource providers
   810  		// to choose from.
   811  		id := prefixes[len(prefixes)-1]
   812  		rn.ResourceProviderNode = fmt.Sprintf("provider.%s", id)
   813  
   814  		// If we don't have a matching noun for this yet, insert it.
   815  		if g.Noun(rn.ResourceProviderNode) == nil {
   816  			pn := &depgraph.Noun{
   817  				Name: rn.ResourceProviderNode,
   818  				Meta: &GraphNodeResourceProvider{
   819  					ID:       id,
   820  					Provider: new(graphSharedProvider),
   821  				},
   822  			}
   823  			g.Nouns = append(g.Nouns, pn)
   824  		}
   825  	}
   826  
   827  	if len(errs) > 0 {
   828  		return &multierror.Error{Errors: errs}
   829  	}
   830  
   831  	return nil
   832  }
   833  
   834  func graphAddModuleOrphans(
   835  	g *depgraph.Graph,
   836  	config *config.Config,
   837  	ms []*ModuleState,
   838  	opts *GraphOpts) error {
   839  	// Build a lookup map for the modules we do have defined
   840  	childrenKeys := make(map[string]struct{})
   841  	for _, m := range config.Modules {
   842  		childrenKeys[m.Name] = struct{}{}
   843  	}
   844  
   845  	// Go through each of the child modules. If we don't have it in our
   846  	// config, it is an orphan.
   847  	var nounsList []*depgraph.Noun
   848  	for _, m := range ms {
   849  		k := m.Path[len(m.Path)-1]
   850  		if _, ok := childrenKeys[k]; ok {
   851  			// We have this module configured
   852  			continue
   853  		}
   854  
   855  		if n, err := graphModuleNoun(k, nil, g, opts); err != nil {
   856  			return err
   857  		} else {
   858  			nounsList = append(nounsList, n)
   859  		}
   860  	}
   861  
   862  	g.Nouns = append(g.Nouns, nounsList...)
   863  	return nil
   864  }
   865  
   866  // graphAddOrphanDeps adds the dependencies to the orphans based on their
   867  // explicit Dependencies state.
   868  func graphAddOrphanDeps(g *depgraph.Graph, mod *ModuleState) {
   869  	for _, n := range g.Nouns {
   870  		rn, ok := n.Meta.(*GraphNodeResource)
   871  		if !ok {
   872  			continue
   873  		}
   874  		if rn.Resource.Flags&FlagOrphan == 0 {
   875  			continue
   876  		}
   877  
   878  		// If we have no dependencies, then just continue
   879  		rs := mod.Resources[n.Name]
   880  		if len(rs.Dependencies) == 0 {
   881  			continue
   882  		}
   883  
   884  		for _, n2 := range g.Nouns {
   885  			// Don't ever depend on ourselves
   886  			if n2.Meta == n.Meta {
   887  				continue
   888  			}
   889  
   890  			var compareName string
   891  			switch rn2 := n2.Meta.(type) {
   892  			case *GraphNodeModule:
   893  				compareName = n2.Name
   894  			case *GraphNodeResource:
   895  				compareName = rn2.Resource.Id
   896  			}
   897  			if compareName == "" {
   898  				continue
   899  			}
   900  
   901  			for _, depName := range rs.Dependencies {
   902  				if !strings.HasPrefix(depName, compareName) {
   903  					continue
   904  				}
   905  				dep := &depgraph.Dependency{
   906  					Name:   depName,
   907  					Source: n,
   908  					Target: n2,
   909  				}
   910  				n.Deps = append(n.Deps, dep)
   911  				break
   912  			}
   913  		}
   914  	}
   915  }
   916  
   917  // graphAddOrphans adds the orphans to the graph.
   918  func graphAddOrphans(g *depgraph.Graph, c *config.Config, mod *ModuleState) {
   919  	meta := g.Meta.(*GraphMeta)
   920  
   921  	var nlist []*depgraph.Noun
   922  	for _, k := range mod.Orphans(c) {
   923  		rs := mod.Resources[k]
   924  		noun := &depgraph.Noun{
   925  			Name: k,
   926  			Meta: &GraphNodeResource{
   927  				Index: -1,
   928  				Resource: &Resource{
   929  					Id: k,
   930  					Info: &InstanceInfo{
   931  						Id:         k,
   932  						ModulePath: meta.ModulePath,
   933  						Type:       rs.Type,
   934  					},
   935  					State:  rs.Primary,
   936  					Config: NewResourceConfig(nil),
   937  					Flags:  FlagOrphan,
   938  				},
   939  			},
   940  		}
   941  
   942  		// Append it to the list so we handle it later
   943  		nlist = append(nlist, noun)
   944  	}
   945  
   946  	// Add the nouns to the graph
   947  	g.Nouns = append(g.Nouns, nlist...)
   948  }
   949  
   950  // graphAddParentProviderConfigs goes through and adds/merges provider
   951  // configurations from the parent.
   952  func graphAddParentProviderConfigs(g, parent *depgraph.Graph) {
   953  	var nounsList []*depgraph.Noun
   954  	for _, n := range parent.Nouns {
   955  		pn, ok := n.Meta.(*GraphNodeResourceProvider)
   956  		if !ok {
   957  			continue
   958  		}
   959  
   960  		// If we have a provider configuration with the exact same
   961  		// name, then set specify the parent pointer to their shared
   962  		// config.
   963  		ourProviderRaw := g.Noun(n.Name)
   964  
   965  		// If we don't have a matching configuration, then create one.
   966  		if ourProviderRaw == nil {
   967  			noun := &depgraph.Noun{
   968  				Name: n.Name,
   969  				Meta: &GraphNodeResourceProvider{
   970  					ID: pn.ID,
   971  					Provider: &graphSharedProvider{
   972  						Parent:     pn.Provider,
   973  						parentNoun: n,
   974  					},
   975  				},
   976  			}
   977  
   978  			nounsList = append(nounsList, noun)
   979  			continue
   980  		}
   981  
   982  		// If we have a matching configuration, then set the parent pointer
   983  		ourProvider := ourProviderRaw.Meta.(*GraphNodeResourceProvider)
   984  		ourProvider.Provider.Parent = pn.Provider
   985  		ourProvider.Provider.parentNoun = n
   986  	}
   987  
   988  	g.Nouns = append(g.Nouns, nounsList...)
   989  }
   990  
   991  // graphAddConfigProviderConfigs adds a GraphNodeResourceProvider for every
   992  // `provider` configuration block. Note that a provider may exist that
   993  // isn't used for any resources. These will be pruned later.
   994  func graphAddConfigProviderConfigs(g *depgraph.Graph, c *config.Config) {
   995  	nounsList := make([]*depgraph.Noun, 0, len(c.ProviderConfigs))
   996  	for _, pc := range c.ProviderConfigs {
   997  		noun := &depgraph.Noun{
   998  			Name: fmt.Sprintf("provider.%s", pc.Name),
   999  			Meta: &GraphNodeResourceProvider{
  1000  				ID: pc.Name,
  1001  				Provider: &graphSharedProvider{
  1002  					Config: pc,
  1003  				},
  1004  			},
  1005  		}
  1006  
  1007  		nounsList = append(nounsList, noun)
  1008  	}
  1009  
  1010  	// Add all the provider config nouns to the graph
  1011  	g.Nouns = append(g.Nouns, nounsList...)
  1012  }
  1013  
  1014  // graphAddRoot adds a root element to the graph so that there is a single
  1015  // root to point to all the dependencies.
  1016  func graphAddRoot(g *depgraph.Graph) {
  1017  	root := &depgraph.Noun{Name: GraphRootNode}
  1018  	for _, n := range g.Nouns {
  1019  		switch n.Meta.(type) {
  1020  		case *GraphNodeResourceProvider:
  1021  			// ResourceProviders don't need to be in the root deps because
  1022  			// they're always pointed to by some resource.
  1023  			continue
  1024  		}
  1025  
  1026  		root.Deps = append(root.Deps, &depgraph.Dependency{
  1027  			Name:   n.Name,
  1028  			Source: root,
  1029  			Target: n,
  1030  		})
  1031  	}
  1032  	g.Nouns = append(g.Nouns, root)
  1033  	g.Root = root
  1034  }
  1035  
  1036  // graphAddVariableDeps inspects all the nouns and adds any dependencies
  1037  // based on variable values.
  1038  func graphAddVariableDeps(g *depgraph.Graph) {
  1039  	for _, n := range g.Nouns {
  1040  		switch m := n.Meta.(type) {
  1041  		case *GraphNodeModule:
  1042  			if m.Config != nil {
  1043  				vars := m.Config.RawConfig.Variables
  1044  				nounAddVariableDeps(g, n, vars, false)
  1045  			}
  1046  
  1047  		case *GraphNodeResource:
  1048  			if m.Config != nil {
  1049  				// Handle the count variables
  1050  				vars := m.Config.RawCount.Variables
  1051  				nounAddVariableDeps(g, n, vars, false)
  1052  
  1053  				// Handle the resource variables
  1054  				vars = m.Config.RawConfig.Variables
  1055  				nounAddVariableDeps(g, n, vars, false)
  1056  			}
  1057  
  1058  			// Handle the variables of the resource provisioners
  1059  			for _, p := range m.Resource.Provisioners {
  1060  				vars := p.RawConfig.Variables
  1061  				nounAddVariableDeps(g, n, vars, true)
  1062  
  1063  				vars = p.ConnInfo.Variables
  1064  				nounAddVariableDeps(g, n, vars, true)
  1065  			}
  1066  
  1067  		case *GraphNodeResourceProvider:
  1068  			if m.Provider != nil && m.Provider.Config != nil {
  1069  				vars := m.Provider.Config.RawConfig.Variables
  1070  				nounAddVariableDeps(g, n, vars, false)
  1071  			}
  1072  
  1073  		default:
  1074  			// Other node types don't have dependencies or we don't support it
  1075  			continue
  1076  		}
  1077  	}
  1078  }
  1079  
  1080  // graphAddTainted adds the tainted instances to the graph.
  1081  func graphAddTainted(g *depgraph.Graph, mod *ModuleState) {
  1082  	meta := g.Meta.(*GraphMeta)
  1083  
  1084  	var nlist []*depgraph.Noun
  1085  	for k, rs := range mod.Resources {
  1086  		// If we have no tainted resources, continue on
  1087  		if len(rs.Tainted) == 0 {
  1088  			continue
  1089  		}
  1090  
  1091  		// Find the untainted resource of this in the noun list. If our
  1092  		// name is 3 parts, then we mus be a count instance, so our
  1093  		// untainted node is just the noun without the count.
  1094  		var untainted *depgraph.Noun
  1095  		untaintedK := k
  1096  		if ps := strings.Split(k, "."); len(ps) == 3 {
  1097  			untaintedK = strings.Join(ps[0:2], ".")
  1098  		}
  1099  		for _, n := range g.Nouns {
  1100  			if n.Name == untaintedK {
  1101  				untainted = n
  1102  				break
  1103  			}
  1104  		}
  1105  
  1106  		for i, is := range rs.Tainted {
  1107  			name := fmt.Sprintf("%s (tainted #%d)", k, i+1)
  1108  
  1109  			// Add each of the tainted resources to the graph, and encode
  1110  			// a dependency from the non-tainted resource to this so that
  1111  			// tainted resources are always destroyed first.
  1112  			noun := &depgraph.Noun{
  1113  				Name: name,
  1114  				Meta: &GraphNodeResource{
  1115  					Index: -1,
  1116  					Resource: &Resource{
  1117  						Id: k,
  1118  						Info: &InstanceInfo{
  1119  							Id:         k,
  1120  							ModulePath: meta.ModulePath,
  1121  							Type:       rs.Type,
  1122  						},
  1123  						State:        is,
  1124  						Config:       NewResourceConfig(nil),
  1125  						Diff:         &InstanceDiff{Destroy: true},
  1126  						Flags:        FlagTainted,
  1127  						TaintedIndex: i,
  1128  					},
  1129  				},
  1130  			}
  1131  
  1132  			// Append it to the list so we handle it later
  1133  			nlist = append(nlist, noun)
  1134  
  1135  			// If we have an untainted version, then make sure to add
  1136  			// the dependency.
  1137  			if untainted != nil {
  1138  				dep := &depgraph.Dependency{
  1139  					Name:   name,
  1140  					Source: untainted,
  1141  					Target: noun,
  1142  				}
  1143  
  1144  				untainted.Deps = append(untainted.Deps, dep)
  1145  			}
  1146  		}
  1147  	}
  1148  
  1149  	// Add the nouns to the graph
  1150  	g.Nouns = append(g.Nouns, nlist...)
  1151  }
  1152  
  1153  // graphModuleNoun creates a noun for a module.
  1154  func graphModuleNoun(
  1155  	n string, m *config.Module,
  1156  	g *depgraph.Graph, opts *GraphOpts) (*depgraph.Noun, error) {
  1157  	name := fmt.Sprintf("module.%s", n)
  1158  	path := make([]string, len(opts.ModulePath)+1)
  1159  	copy(path, opts.ModulePath)
  1160  	path[len(opts.ModulePath)] = n
  1161  
  1162  	// Build the opts we'll use to make the next graph
  1163  	subOpts := *opts
  1164  	subOpts.ModulePath = path
  1165  	subOpts.parent = g
  1166  	subGraph, err := Graph(&subOpts)
  1167  	if err != nil {
  1168  		return nil, fmt.Errorf(
  1169  			"Error building module graph '%s': %s",
  1170  			n, err)
  1171  	}
  1172  
  1173  	return &depgraph.Noun{
  1174  		Name: name,
  1175  		Meta: &GraphNodeModule{
  1176  			Config: m,
  1177  			Path:   path,
  1178  			Graph:  subGraph,
  1179  		},
  1180  	}, nil
  1181  }
  1182  
  1183  // nounAddVariableDeps updates the dependencies of a noun given
  1184  // a set of associated variable values
  1185  func nounAddVariableDeps(
  1186  	g *depgraph.Graph,
  1187  	n *depgraph.Noun,
  1188  	vars map[string]config.InterpolatedVariable,
  1189  	removeSelf bool) {
  1190  	for _, rawV := range vars {
  1191  		var name string
  1192  		var target *depgraph.Noun
  1193  
  1194  		switch v := rawV.(type) {
  1195  		case *config.ModuleVariable:
  1196  			name = fmt.Sprintf("module.%s", v.Name)
  1197  			target = g.Noun(name)
  1198  		case *config.ResourceVariable:
  1199  			// For resource variables, if we ourselves are a resource, then
  1200  			// we have to check whether to expand or not to create the proper
  1201  			// resource dependency.
  1202  			rn, ok := n.Meta.(*GraphNodeResource)
  1203  			if !ok || rn.ExpandMode > ResourceExpandNone {
  1204  				name = v.ResourceId()
  1205  				target = g.Noun(v.ResourceId())
  1206  				break
  1207  			}
  1208  
  1209  			// We're an expanded resource, so add the specific index
  1210  			// as the dependency.
  1211  			name = fmt.Sprintf("%s.%d", v.ResourceId(), v.Index)
  1212  			target = g.Noun(name)
  1213  		default:
  1214  		}
  1215  
  1216  		if target == nil {
  1217  			continue
  1218  		}
  1219  
  1220  		// If we're ignoring self-references, then don't add that
  1221  		// dependency.
  1222  		if removeSelf && n == target {
  1223  			continue
  1224  		}
  1225  
  1226  		// Build the dependency
  1227  		dep := &depgraph.Dependency{
  1228  			Name:   name,
  1229  			Source: n,
  1230  			Target: target,
  1231  		}
  1232  
  1233  		n.Deps = append(n.Deps, dep)
  1234  	}
  1235  }
  1236  
  1237  // graphInitResourceProviders maps the resource providers onto the graph
  1238  // given a mapping of prefixes to resource providers.
  1239  //
  1240  // Unlike the graphAdd* functions, this one can return an error if resource
  1241  // providers can't be found or can't be instantiated.
  1242  func graphInitResourceProviders(
  1243  	g *depgraph.Graph,
  1244  	ps map[string]ResourceProviderFactory) error {
  1245  	var errs []error
  1246  
  1247  	// Keep track of providers we know we couldn't instantiate so
  1248  	// that we don't get a ton of errors about the same provider.
  1249  	failures := make(map[string]struct{})
  1250  
  1251  	for _, n := range g.Nouns {
  1252  		// We only care about the resource providers first. There is guaranteed
  1253  		// to be only one node per tuple (providerId, providerConfig), which
  1254  		// means we don't need to verify we have instantiated it before.
  1255  		rn, ok := n.Meta.(*GraphNodeResourceProvider)
  1256  		if !ok {
  1257  			continue
  1258  		}
  1259  
  1260  		prefixes := matchingPrefixes(rn.ID, ps)
  1261  		if len(prefixes) > 0 {
  1262  			if _, ok := failures[prefixes[0]]; ok {
  1263  				// We already failed this provider, meaning this
  1264  				// resource will never succeed, so just continue.
  1265  				continue
  1266  			}
  1267  		}
  1268  
  1269  		sharedProvider := rn.Provider
  1270  
  1271  		// Go through each prefix and instantiate if necessary, then
  1272  		// verify if this provider is of use to us or not.
  1273  		sharedProvider.Providers = make(map[string]ResourceProvider)
  1274  		sharedProvider.ProviderKeys = prefixes
  1275  		for _, prefix := range prefixes {
  1276  			p, err := ps[prefix]()
  1277  			if err != nil {
  1278  				errs = append(errs, fmt.Errorf(
  1279  					"Error instantiating resource provider for "+
  1280  						"prefix %s: %s", prefix, err))
  1281  
  1282  				// Record the error so that we don't check it again
  1283  				failures[prefix] = struct{}{}
  1284  
  1285  				// Jump to the next prefix
  1286  				continue
  1287  			}
  1288  
  1289  			sharedProvider.Providers[prefix] = p
  1290  		}
  1291  
  1292  		// If we never found a provider, then error and continue
  1293  		if len(sharedProvider.Providers) == 0 {
  1294  			errs = append(errs, fmt.Errorf(
  1295  				"Provider for configuration '%s' not found.",
  1296  				rn.ID))
  1297  			continue
  1298  		}
  1299  	}
  1300  
  1301  	if len(errs) > 0 {
  1302  		return &multierror.Error{Errors: errs}
  1303  	}
  1304  
  1305  	return nil
  1306  }
  1307  
  1308  // graphAddResourceProviderDeps goes through all the nodes in the graph
  1309  // and adds any dependencies to resource providers as needed.
  1310  func graphAddResourceProviderDeps(g *depgraph.Graph) {
  1311  	for _, rawN := range g.Nouns {
  1312  		switch n := rawN.Meta.(type) {
  1313  		case *GraphNodeModule:
  1314  			// Check if the module depends on any of our providers
  1315  			// by seeing if there is a parent node back.
  1316  			for _, moduleRaw := range n.Graph.Nouns {
  1317  				pn, ok := moduleRaw.Meta.(*GraphNodeResourceProvider)
  1318  				if !ok {
  1319  					continue
  1320  				}
  1321  				if pn.Provider.parentNoun == nil {
  1322  					continue
  1323  				}
  1324  
  1325  				// Create the dependency to the provider
  1326  				dep := &depgraph.Dependency{
  1327  					Name:   pn.Provider.parentNoun.Name,
  1328  					Source: rawN,
  1329  					Target: pn.Provider.parentNoun,
  1330  				}
  1331  				rawN.Deps = append(rawN.Deps, dep)
  1332  			}
  1333  		case *GraphNodeResource:
  1334  			// Not sure how this would happen, but we might as well
  1335  			// check for it.
  1336  			if n.ResourceProviderNode == "" {
  1337  				continue
  1338  			}
  1339  
  1340  			// Get the noun this depends on.
  1341  			target := g.Noun(n.ResourceProviderNode)
  1342  
  1343  			// Create the dependency to the provider
  1344  			dep := &depgraph.Dependency{
  1345  				Name:   target.Name,
  1346  				Source: rawN,
  1347  				Target: target,
  1348  			}
  1349  			rawN.Deps = append(rawN.Deps, dep)
  1350  		}
  1351  	}
  1352  }
  1353  
  1354  // graphPruneResourceProviders will remove the GraphNodeResourceProvider
  1355  // nodes that aren't used in any way.
  1356  func graphPruneResourceProviders(g *depgraph.Graph) {
  1357  	// First, build a mapping of the providers we have.
  1358  	ps := make(map[string]struct{})
  1359  	for _, n := range g.Nouns {
  1360  		_, ok := n.Meta.(*GraphNodeResourceProvider)
  1361  		if !ok {
  1362  			continue
  1363  		}
  1364  
  1365  		ps[n.Name] = struct{}{}
  1366  	}
  1367  
  1368  	// Now go through all the dependencies throughout and find
  1369  	// if any of these aren't reachable.
  1370  	for _, n := range g.Nouns {
  1371  		for _, dep := range n.Deps {
  1372  			delete(ps, dep.Target.Name)
  1373  		}
  1374  	}
  1375  
  1376  	if len(ps) == 0 {
  1377  		// We used all of them!
  1378  		return
  1379  	}
  1380  
  1381  	// Now go through and remove these nodes that aren't used
  1382  	for i := 0; i < len(g.Nouns); i++ {
  1383  		if _, ok := ps[g.Nouns[i].Name]; !ok {
  1384  			continue
  1385  		}
  1386  
  1387  		// Delete this node
  1388  		copy(g.Nouns[i:], g.Nouns[i+1:])
  1389  		g.Nouns[len(g.Nouns)-1] = nil
  1390  		g.Nouns = g.Nouns[:len(g.Nouns)-1]
  1391  		i--
  1392  	}
  1393  }
  1394  
  1395  // graphMapResourceProviderId goes through the graph and maps the
  1396  // ID of a resource provider node to each resource. This lets us know which
  1397  // configuration is for which resource.
  1398  //
  1399  // This is safe to call multiple times.
  1400  func graphMapResourceProviderId(g *depgraph.Graph) {
  1401  	// Build the list of provider configs we have
  1402  	ps := make(map[string]string)
  1403  	for _, n := range g.Nouns {
  1404  		pn, ok := n.Meta.(*GraphNodeResourceProvider)
  1405  		if !ok {
  1406  			continue
  1407  		}
  1408  
  1409  		ps[n.Name] = pn.ID
  1410  	}
  1411  
  1412  	// Go through every resource and find the shortest matching provider
  1413  	for _, n := range g.Nouns {
  1414  		rn, ok := n.Meta.(*GraphNodeResource)
  1415  		if !ok {
  1416  			continue
  1417  		}
  1418  
  1419  		var match, matchNode string
  1420  		for n, p := range ps {
  1421  			if !strings.HasPrefix(rn.Resource.Info.Type, p) {
  1422  				continue
  1423  			}
  1424  			if len(p) > len(match) {
  1425  				match = p
  1426  				matchNode = n
  1427  			}
  1428  		}
  1429  		if matchNode == "" {
  1430  			continue
  1431  		}
  1432  
  1433  		rn.ResourceProviderNode = matchNode
  1434  	}
  1435  }
  1436  
  1437  // graphMapResourceProviders takes a graph that already has initialized
  1438  // the resource providers (using graphInitResourceProviders) and maps the
  1439  // resource providers to the resources themselves.
  1440  func graphMapResourceProviders(g *depgraph.Graph) error {
  1441  	var errs []error
  1442  
  1443  	// First build a mapping of resource provider ID to the node that
  1444  	// contains those resources.
  1445  	mapping := make(map[string]*GraphNodeResourceProvider)
  1446  	for _, n := range g.Nouns {
  1447  		rn, ok := n.Meta.(*GraphNodeResourceProvider)
  1448  		if !ok {
  1449  			continue
  1450  		}
  1451  		mapping[rn.ID] = rn
  1452  	}
  1453  
  1454  	// Now go through each of the resources and find a matching provider.
  1455  	for _, n := range g.Nouns {
  1456  		rn, ok := n.Meta.(*GraphNodeResource)
  1457  		if !ok {
  1458  			continue
  1459  		}
  1460  
  1461  		rpnRaw := g.Noun(rn.ResourceProviderNode)
  1462  		if rpnRaw == nil {
  1463  			// This should never happen since when building the graph
  1464  			// we ensure that everything matches up.
  1465  			panic(fmt.Sprintf(
  1466  				"Resource provider not found: %s (type: %s)",
  1467  				rn.ResourceProviderNode,
  1468  				rn.Resource.Info.Type))
  1469  		}
  1470  		rpn := rpnRaw.Meta.(*GraphNodeResourceProvider)
  1471  
  1472  		var provider ResourceProvider
  1473  		for _, k := range rpn.Provider.ProviderKeys {
  1474  			// Only try this provider if it has the right prefix
  1475  			if !strings.HasPrefix(rn.Resource.Info.Type, k) {
  1476  				continue
  1477  			}
  1478  
  1479  			rp := rpn.Provider.Providers[k]
  1480  			if ProviderSatisfies(rp, rn.Resource.Info.Type) {
  1481  				provider = rp
  1482  				break
  1483  			}
  1484  		}
  1485  
  1486  		if provider == nil {
  1487  			errs = append(errs, fmt.Errorf(
  1488  				"Resource provider not found for resource type '%s'",
  1489  				rn.Resource.Info.Type))
  1490  			continue
  1491  		}
  1492  
  1493  		rn.Resource.Provider = provider
  1494  	}
  1495  
  1496  	if len(errs) > 0 {
  1497  		return &multierror.Error{Errors: errs}
  1498  	}
  1499  
  1500  	return nil
  1501  }
  1502  
  1503  // graphMapResourceProvisioners takes a graph that already has
  1504  // the resources and maps the resource provisioners to the resources themselves.
  1505  func graphMapResourceProvisioners(g *depgraph.Graph,
  1506  	provisioners map[string]ResourceProvisionerFactory) error {
  1507  	var errs []error
  1508  
  1509  	// Create a cache of resource provisioners, avoids duplicate
  1510  	// initialization of the instances
  1511  	cache := make(map[string]ResourceProvisioner)
  1512  
  1513  	// Go through each of the resources and find a matching provisioners
  1514  	for _, n := range g.Nouns {
  1515  		rn, ok := n.Meta.(*GraphNodeResource)
  1516  		if !ok {
  1517  			continue
  1518  		}
  1519  
  1520  		// Ignore orphan nodes with no provisioners
  1521  		if rn.Config == nil {
  1522  			continue
  1523  		}
  1524  
  1525  		// Check each provisioner
  1526  		for _, p := range rn.Config.Provisioners {
  1527  			// Check for a cached provisioner
  1528  			provisioner, ok := cache[p.Type]
  1529  			if !ok {
  1530  				// Lookup the factory method
  1531  				factory, ok := provisioners[p.Type]
  1532  				if !ok {
  1533  					errs = append(errs, fmt.Errorf(
  1534  						"Resource provisioner not found for provisioner type '%s'",
  1535  						p.Type))
  1536  					continue
  1537  				}
  1538  
  1539  				// Initialize the provisioner
  1540  				prov, err := factory()
  1541  				if err != nil {
  1542  					errs = append(errs, fmt.Errorf(
  1543  						"Failed to instantiate provisioner type '%s': %v",
  1544  						p.Type, err))
  1545  					continue
  1546  				}
  1547  				provisioner = prov
  1548  
  1549  				// Cache this type of provisioner
  1550  				cache[p.Type] = prov
  1551  			}
  1552  
  1553  			// Save the provisioner
  1554  			rn.Resource.Provisioners = append(rn.Resource.Provisioners, &ResourceProvisionerConfig{
  1555  				Type:        p.Type,
  1556  				Provisioner: provisioner,
  1557  				Config:      NewResourceConfig(p.RawConfig),
  1558  				RawConfig:   p.RawConfig,
  1559  				ConnInfo:    p.ConnInfo,
  1560  			})
  1561  		}
  1562  	}
  1563  
  1564  	if len(errs) > 0 {
  1565  		return &multierror.Error{Errors: errs}
  1566  	}
  1567  	return nil
  1568  }
  1569  
  1570  // grpahRemoveInvalidDeps goes through the graph and removes dependencies
  1571  // that no longer exist.
  1572  func graphRemoveInvalidDeps(g *depgraph.Graph) {
  1573  	check := make(map[*depgraph.Noun]struct{})
  1574  	for _, n := range g.Nouns {
  1575  		check[n] = struct{}{}
  1576  	}
  1577  	for _, n := range g.Nouns {
  1578  		deps := n.Deps
  1579  		num := len(deps)
  1580  		for i := 0; i < num; i++ {
  1581  			if _, ok := check[deps[i].Target]; !ok {
  1582  				deps[i], deps[num-1] = deps[num-1], nil
  1583  				i--
  1584  				num--
  1585  			}
  1586  		}
  1587  		n.Deps = deps[:num]
  1588  	}
  1589  }
  1590  
  1591  // MergeConfig merges all the configurations in the proper order
  1592  // to result in the final configuration to use to configure this
  1593  // provider.
  1594  func (p *graphSharedProvider) MergeConfig(
  1595  	raw bool, override map[string]interface{}) *ResourceConfig {
  1596  	var rawMap map[string]interface{}
  1597  	if override != nil {
  1598  		rawMap = override
  1599  	} else if p.Config != nil {
  1600  		rawMap = p.Config.RawConfig.Raw
  1601  	}
  1602  	if rawMap == nil {
  1603  		rawMap = make(map[string]interface{})
  1604  	}
  1605  
  1606  	// Merge in all the parent configurations
  1607  	if p.Parent != nil {
  1608  		parent := p.Parent
  1609  		for parent != nil {
  1610  			if parent.Config != nil {
  1611  				var merge map[string]interface{}
  1612  				if raw {
  1613  					merge = parent.Config.RawConfig.Raw
  1614  				} else {
  1615  					merge = parent.Config.RawConfig.Config()
  1616  				}
  1617  
  1618  				for k, v := range merge {
  1619  					rawMap[k] = v
  1620  				}
  1621  			}
  1622  
  1623  			parent = parent.Parent
  1624  		}
  1625  	}
  1626  
  1627  	rc, err := config.NewRawConfig(rawMap)
  1628  	if err != nil {
  1629  		panic("error building config: " + err.Error())
  1630  	}
  1631  
  1632  	return NewResourceConfig(rc)
  1633  }
  1634  
  1635  // Expand will expand this node into a subgraph if Expand is set.
  1636  func (n *GraphNodeResource) Expand() (*depgraph.Graph, error) {
  1637  	// Expand the count out, which should be interpolated at this point.
  1638  	count, err := n.Config.Count()
  1639  	if err != nil {
  1640  		return nil, err
  1641  	}
  1642  	log.Printf("[DEBUG] %s: expanding to count = %d", n.Resource.Id, count)
  1643  
  1644  	// TODO: can we DRY this up?
  1645  	g := new(depgraph.Graph)
  1646  	g.Meta = &GraphMeta{
  1647  		ModulePath: n.Resource.Info.ModulePath,
  1648  	}
  1649  
  1650  	// Determine the nodes to create. If we're just looking for the
  1651  	// nodes to create, return that.
  1652  	n.expand(g, count)
  1653  
  1654  	// Add in the diff if we have it
  1655  	if n.Diff != nil {
  1656  		if err := graphAddDiff(g, n.Diff); err != nil {
  1657  			return nil, err
  1658  		}
  1659  	}
  1660  
  1661  	// Add all the variable dependencies
  1662  	graphAddVariableDeps(g)
  1663  
  1664  	// If we're just expanding the apply, then filter those out and
  1665  	// return them now.
  1666  	if n.ExpandMode == ResourceExpandApply {
  1667  		return n.finalizeGraph(g, false)
  1668  	}
  1669  
  1670  	if n.State != nil {
  1671  		// Add the tainted resources
  1672  		graphAddTainted(g, n.State)
  1673  	}
  1674  
  1675  	return n.finalizeGraph(g, true)
  1676  }
  1677  
  1678  // expand expands this resource and adds the resources to the graph. It
  1679  // adds both create and destroy resources.
  1680  func (n *GraphNodeResource) expand(g *depgraph.Graph, count int) {
  1681  	// Create the list of nouns
  1682  	result := make([]*depgraph.Noun, 0, count)
  1683  
  1684  	// Build the key set so we know what is removed
  1685  	var keys map[string]struct{}
  1686  	if n.State != nil {
  1687  		keys = make(map[string]struct{})
  1688  		for k, _ := range n.State.Resources {
  1689  			keys[k] = struct{}{}
  1690  		}
  1691  	}
  1692  
  1693  	// First thing, expand the counts that we have defined for our
  1694  	// current config into the full set of resources that are being
  1695  	// created.
  1696  	r := n.Config
  1697  	for i := 0; i < count; i++ {
  1698  		name := r.Id()
  1699  		index := -1
  1700  
  1701  		// If we have a count that is more than one, then make sure
  1702  		// we suffix with the number of the resource that this is.
  1703  		if count > 1 {
  1704  			name = fmt.Sprintf("%s.%d", name, i)
  1705  			index = i
  1706  		}
  1707  
  1708  		var state *ResourceState
  1709  		if n.State != nil {
  1710  			// Lookup the resource state
  1711  			if s, ok := n.State.Resources[name]; ok {
  1712  				state = s
  1713  				delete(keys, name)
  1714  			}
  1715  
  1716  			if state == nil {
  1717  				if count == 1 {
  1718  					// If the count is one, check the state for ".0"
  1719  					// appended, which might exist if we go from
  1720  					// count > 1 to count == 1.
  1721  					k := r.Id() + ".0"
  1722  					state = n.State.Resources[k]
  1723  					delete(keys, k)
  1724  				} else if i == 0 {
  1725  					// If count is greater than one, check for state
  1726  					// with just the ID, which might exist if we go
  1727  					// from count == 1 to count > 1
  1728  					state = n.State.Resources[r.Id()]
  1729  					delete(keys, r.Id())
  1730  				}
  1731  			}
  1732  		}
  1733  
  1734  		if state == nil {
  1735  			state = &ResourceState{
  1736  				Type: r.Type,
  1737  			}
  1738  		}
  1739  
  1740  		flags := FlagPrimary
  1741  		if len(state.Tainted) > 0 {
  1742  			flags |= FlagHasTainted
  1743  		}
  1744  
  1745  		// Copy the base resource so we can fill it in
  1746  		resource := n.copyResource(name)
  1747  		resource.CountIndex = i
  1748  		resource.State = state.Primary
  1749  		resource.Flags = flags
  1750  
  1751  		// Add the result
  1752  		result = append(result, &depgraph.Noun{
  1753  			Name: name,
  1754  			Meta: &GraphNodeResource{
  1755  				Index:    index,
  1756  				Config:   r,
  1757  				Resource: resource,
  1758  			},
  1759  		})
  1760  	}
  1761  
  1762  	// Go over the leftover keys which are orphans (decreasing counts)
  1763  	for k, _ := range keys {
  1764  		rs := n.State.Resources[k]
  1765  
  1766  		resource := n.copyResource(k)
  1767  		resource.Config = NewResourceConfig(nil)
  1768  		resource.State = rs.Primary
  1769  		resource.Flags = FlagOrphan
  1770  
  1771  		noun := &depgraph.Noun{
  1772  			Name: k,
  1773  			Meta: &GraphNodeResource{
  1774  				Index:    -1,
  1775  				Resource: resource,
  1776  			},
  1777  		}
  1778  
  1779  		result = append(result, noun)
  1780  	}
  1781  
  1782  	g.Nouns = append(g.Nouns, result...)
  1783  }
  1784  
  1785  // copyResource copies the Resource structure to assign to a subgraph.
  1786  func (n *GraphNodeResource) copyResource(id string) *Resource {
  1787  	info := *n.Resource.Info
  1788  	info.Id = id
  1789  	resource := *n.Resource
  1790  	resource.Id = id
  1791  	resource.Info = &info
  1792  	resource.Config = NewResourceConfig(n.Config.RawConfig)
  1793  	resource.Diff = nil
  1794  	return &resource
  1795  }
  1796  
  1797  func (n *GraphNodeResource) finalizeGraph(
  1798  	g *depgraph.Graph, destroy bool) (*depgraph.Graph, error) {
  1799  	result := make([]*depgraph.Noun, 0, len(g.Nouns))
  1800  	for _, n := range g.Nouns {
  1801  		rn, ok := n.Meta.(*GraphNodeResource)
  1802  		if !ok {
  1803  			continue
  1804  		}
  1805  
  1806  		// If the diff is nil, then we're not destroying, so append only
  1807  		// in that case.
  1808  		if rn.Resource.Diff == nil {
  1809  			if !destroy {
  1810  				result = append(result, n)
  1811  			}
  1812  
  1813  			continue
  1814  		}
  1815  
  1816  		// If we are destroying, append it only if we care about destroys
  1817  		if rn.Resource.Diff.Destroy {
  1818  			if destroy {
  1819  				result = append(result, n)
  1820  			}
  1821  
  1822  			continue
  1823  		}
  1824  
  1825  		// If this is an oprhan, we only care about it if we're destroying.
  1826  		if rn.Resource.Flags&FlagOrphan != 0 {
  1827  			if destroy {
  1828  				result = append(result, n)
  1829  			}
  1830  
  1831  			continue
  1832  		}
  1833  
  1834  		// If we're not destroying, then add it only if we don't
  1835  		// care about deploys.
  1836  		if !destroy {
  1837  			result = append(result, n)
  1838  		}
  1839  	}
  1840  
  1841  	// Set the nouns to be only those we care about
  1842  	g.Nouns = result
  1843  
  1844  	// Remove the dependencies that don't exist
  1845  	graphRemoveInvalidDeps(g)
  1846  
  1847  	// Build the root so that we have a single valid root
  1848  	graphAddRoot(g)
  1849  
  1850  	// Validate
  1851  	if err := g.Validate(); err != nil {
  1852  		return nil, err
  1853  	}
  1854  
  1855  	return g, nil
  1856  }
  1857  
  1858  // matchingPrefixes takes a resource type and a set of resource
  1859  // providers we know about by prefix and returns a list of prefixes
  1860  // that might be valid for that resource.
  1861  //
  1862  // The list returned is in the order that they should be attempted.
  1863  func matchingPrefixes(
  1864  	t string,
  1865  	ps map[string]ResourceProviderFactory) []string {
  1866  	result := make([]string, 0, 1)
  1867  	for prefix, _ := range ps {
  1868  		if strings.HasPrefix(t, prefix) {
  1869  			result = append(result, prefix)
  1870  		}
  1871  	}
  1872  
  1873  	// Sort by longest first
  1874  	sort.Sort(stringLenSort(result))
  1875  
  1876  	return result
  1877  }
  1878  
  1879  // stringLenSort implements sort.Interface and sorts strings in increasing
  1880  // length order. i.e. "a", "aa", "aaa"
  1881  type stringLenSort []string
  1882  
  1883  func (s stringLenSort) Len() int {
  1884  	return len(s)
  1885  }
  1886  
  1887  func (s stringLenSort) Less(i, j int) bool {
  1888  	return len(s[i]) < len(s[j])
  1889  }
  1890  
  1891  func (s stringLenSort) Swap(i, j int) {
  1892  	s[i], s[j] = s[j], s[i]
  1893  }