diff --git a/terraform/graph_builder_apply.go b/terraform/graph_builder_apply.go index 2721e7113..cee423b91 100644 --- a/terraform/graph_builder_apply.go +++ b/terraform/graph_builder_apply.go @@ -84,9 +84,6 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer { // Attach the state &AttachStateTransformer{State: b.State}, - // add providers - TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config), - // Destruction ordering &DestroyEdgeTransformer{ Config: b.Config, @@ -118,6 +115,9 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer { // Add module variables &ModuleVariableTransformer{Config: b.Config}, + // add providers + TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config), + // Remove modules no longer present in the config &RemovedModuleTransformer{Config: b.Config, State: b.State}, diff --git a/terraform/graph_builder_plan.go b/terraform/graph_builder_plan.go index 4e74587be..fffa5554a 100644 --- a/terraform/graph_builder_plan.go +++ b/terraform/graph_builder_plan.go @@ -101,8 +101,6 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer { // Add root variables &RootVariableTransformer{Config: b.Config}, - TransformProviders(b.Components.ResourceProviders(), b.ConcreteProvider, b.Config), - &MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()}, &AttachSchemaTransformer{Components: b.Components}, @@ -112,6 +110,8 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer { Config: b.Config, }, + TransformProviders(b.Components.ResourceProviders(), b.ConcreteProvider, b.Config), + // Remove modules no longer present in the config &RemovedModuleTransformer{Config: b.Config, State: b.State}, diff --git a/terraform/graph_builder_refresh.go b/terraform/graph_builder_refresh.go index a6c5373d4..b5d7d3208 100644 --- a/terraform/graph_builder_refresh.go +++ b/terraform/graph_builder_refresh.go @@ -125,8 +125,6 @@ func (b *RefreshGraphBuilder) Steps() []GraphTransformer { // Add root variables &RootVariableTransformer{Config: b.Config}, - TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config), - // Add the local values &LocalTransformer{Config: b.Config}, @@ -136,6 +134,8 @@ func (b *RefreshGraphBuilder) Steps() []GraphTransformer { // Add module variables &ModuleVariableTransformer{Config: b.Config}, + TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config), + // Must be before ReferenceTransformer, since schema is required to // extract references from config. &AttachSchemaTransformer{Components: b.Components}, diff --git a/terraform/test-fixtures/apply-targeted-module-unrelated-outputs/child2/main.tf b/terraform/test-fixtures/apply-targeted-module-unrelated-outputs/child2/main.tf index dce2d167b..d8aa6cf35 100644 --- a/terraform/test-fixtures/apply-targeted-module-unrelated-outputs/child2/main.tf +++ b/terraform/test-fixtures/apply-targeted-module-unrelated-outputs/child2/main.tf @@ -2,7 +2,7 @@ resource "aws_instance" "foo" { } output "instance_id" { - # Even though we're targeting just the resource a bove, this should still + # Even though we're targeting just the resource above, this should still # be populated because outputs are implicitly targeted when their # dependencies are value = "${aws_instance.foo.id}" diff --git a/terraform/transform_provider.go b/terraform/transform_provider.go index fc0101e44..e31cb20b5 100644 --- a/terraform/transform_provider.go +++ b/terraform/transform_provider.go @@ -134,6 +134,43 @@ func (t *ProviderTransformer) Transform(g *Graph) error { pv.SetProvider(target.ProviderAddr()) g.Connect(dag.BasicEdge(v, target)) } + + if pv, ok := v.(GraphNodeReferencer); ok { + // not a provider consumer, so check if this node references any + // providers + for _, r := range pv.References() { + var res addrs.Resource + switch sub := r.Subject.(type) { + case addrs.ResourceInstance: + res = sub.Resource + case addrs.Resource: + res = sub + default: + continue + } + + providerCfg := res.DefaultProviderConfig() + providerName := providerCfg.String() + + provider := m[providerName] + if provider == nil { + // create the missing top-level provider + // This provider node will only be initialized to provide + // the schema for its referrers. + provider = &NodeEvalableProvider{ + &NodeAbstractProvider{ + Addr: addrs.RootModuleInstance.ProviderConfigDefault(providerCfg.Type), + }, + } + + g.Add(provider) + m[providerName] = provider + } + + log.Printf("[DEBUG] %s references %s", dag.VertexName(pv), providerName) + g.Connect(dag.BasicEdge(pv, provider)) + } + } } return err