mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-27 17:06:27 -06:00
connect non-resources to providers they reference
Any non-resource (outputs, variables, locals) that references a resource type must also be connected to that resources provider. This is required during apply, because the graph built from the diff may not include the referenced resources because they are being evaluated from the state. If the provider isn't present already, add a NodeEvalableProvider to fetch the provider schema. The provider transformers now need to happen after the outputs, locals, and variables are transformed.
This commit is contained in:
parent
1f859ba8d4
commit
4d2da4d733
@ -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},
|
||||
|
||||
|
@ -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},
|
||||
|
||||
|
@ -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},
|
||||
|
@ -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}"
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user