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