diff --git a/terraform/graph_builder_apply.go b/terraform/graph_builder_apply.go index 430195c7f..1b898926e 100644 --- a/terraform/graph_builder_apply.go +++ b/terraform/graph_builder_apply.go @@ -87,6 +87,13 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer { // Attach the state &AttachStateTransformer{State: b.State}, + // add configured providers + &ProviderConfigTransformer{ + Module: b.Module, + Providers: b.Providers, + Concrete: concreteProvider, + }, + // Create all the providers &MissingProviderTransformer{Providers: b.Providers, Concrete: concreteProvider}, &ProviderTransformer{}, diff --git a/terraform/graph_builder_plan.go b/terraform/graph_builder_plan.go index 429e42481..1b93a5ab3 100644 --- a/terraform/graph_builder_plan.go +++ b/terraform/graph_builder_plan.go @@ -93,6 +93,13 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer { // Add root variables &RootVariableTransformer{Module: b.Module}, + // add configured providers + &ProviderConfigTransformer{ + Module: b.Module, + Providers: b.Providers, + Concrete: b.ConcreteProvider, + }, + // Create all the providers &MissingProviderTransformer{Providers: b.Providers, Concrete: b.ConcreteProvider}, &ProviderTransformer{}, diff --git a/terraform/transform_config.go b/terraform/transform_config.go index 61bce8532..7ec7744a7 100644 --- a/terraform/transform_config.go +++ b/terraform/transform_config.go @@ -133,3 +133,78 @@ func (t *ConfigTransformer) transformSingle(g *Graph, m *module.Tree) error { return nil } + +type ProviderConfigTransformer struct { + Providers []string + Concrete ConcreteProviderNodeFunc + + // Module is the module to add resources from. + Module *module.Tree +} + +func (t *ProviderConfigTransformer) Transform(g *Graph) error { + // If no module is given, we don't do anything + if t.Module == nil { + return nil + } + + // If the module isn't loaded, that is simply an error + if !t.Module.Loaded() { + return errors.New("module must be loaded for ProviderConfigTransformer") + } + + // Start the transformation process + return t.transform(g, t.Module) +} + +func (t *ProviderConfigTransformer) transform(g *Graph, m *module.Tree) error { + // If no config, do nothing + if m == nil { + return nil + } + + // Add our resources + if err := t.transformSingle(g, m); err != nil { + return err + } + + // Transform all the children. + for _, c := range m.Children() { + if err := t.transform(g, c); err != nil { + return err + } + } + + return nil +} + +func (t *ProviderConfigTransformer) transformSingle(g *Graph, m *module.Tree) error { + log.Printf("[TRACE] ProviderConfigTransformer: Starting for path: %v", m.Path()) + + // Get the configuration for this module + conf := m.Config() + + // Build the path we're at + path := m.Path() + if len(path) > 0 { + path = append([]string{RootModuleName}, path...) + } + + // Write all the resources out + for _, p := range conf.ProviderConfigs { + name := p.Name + if p.Alias != "" { + name += "." + p.Alias + } + + v := t.Concrete(&NodeAbstractProvider{ + NameValue: name, + PathValue: path, + }).(dag.Vertex) + + // Add it to the graph + g.Add(v) + } + + return nil +} diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index b9695d524..baf3016b9 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -104,10 +104,10 @@ func (t *CloseProviderTransformer) Transform(g *Graph) error { return err } -// MissingProviderTransformer is a GraphTransformer that adds nodes -// for missing providers into the graph. Specifically, it creates provider -// configuration nodes for all the providers that we support. These are -// pruned later during an optimization pass. +// MissingProviderTransformer is a GraphTransformer that adds nodes for all +// required providers into the graph. Specifically, it creates provider +// configuration nodes for all the providers that we support. These are pruned +// later during an optimization pass. type MissingProviderTransformer struct { // Providers is the list of providers we support. Providers []string @@ -160,6 +160,18 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error { } for _, p := range pv.ProvidedBy() { + // always add the parent nodes to check, since configured providers + // may have already been added for modules. + if len(path) > 0 { + // We'll need the parent provider as well, so let's + // add a dummy node to check to make sure that we add + // that parent provider. + check = append(check, &graphNodeProviderConsumerDummy{ + ProviderValue: p, + PathValue: path[:len(path)-1], + }) + } + key := providerMapKey(p, pv) if _, ok := m[key]; ok { // This provider already exists as a configure node @@ -185,16 +197,6 @@ func (t *MissingProviderTransformer) Transform(g *Graph) error { NameValue: p, PathValue: path, }).(dag.Vertex) - if len(path) > 0 { - // We'll need the parent provider as well, so let's - // add a dummy node to check to make sure that we add - // that parent provider. - check = append(check, &graphNodeProviderConsumerDummy{ - ProviderValue: p, - PathValue: path[:len(path)-1], - }) - } - m[key] = g.Add(v) } }