core: Don't create indirect provider dependencies for references
The prior commit changed the schema-access model so that all schemas are fetched up front during context creation and are then readily available for use throughout graph building and evaluation. As a result, we no longer need to create dependency edges to a provider when one of its resources is referenced by another node, and so the ProviderTransformer needs only to worry about direct ownership dependencies. This also avoids the need for us to run AttachSchemaTransformer twice, since ProviderTransformer no longer needs schema and we can therefore defer attaching until just before ReferenceTransformer, when all of the referencable and referencing nodes are already present in the graph.
This commit is contained in:
parent
d3e4565681
commit
71cedf19a4
|
@ -119,21 +119,16 @@ func (b *ApplyGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Add module variables
|
// Add module variables
|
||||||
&ModuleVariableTransformer{Config: b.Config},
|
&ModuleVariableTransformer{Config: b.Config},
|
||||||
|
|
||||||
// Must be run before TransformProviders so that resource configurations
|
|
||||||
// can be analyzed.
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
// add providers
|
// add providers
|
||||||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
||||||
|
|
||||||
// Attach schema to the newly-created provider nodes.
|
|
||||||
// (Will also redundantly re-attach schema to existing resource nodes,
|
|
||||||
// but that's okay.)
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
// Remove modules no longer present in the config
|
// Remove modules no longer present in the config
|
||||||
&RemovedModuleTransformer{Config: b.Config, State: b.State},
|
&RemovedModuleTransformer{Config: b.Config, State: b.State},
|
||||||
|
|
||||||
|
// Must attach schemas before ReferenceTransformer so that we can
|
||||||
|
// analyze the configuration to find references.
|
||||||
|
&AttachSchemaTransformer{Schemas: b.Schemas},
|
||||||
|
|
||||||
// Connect references so ordering is correct
|
// Connect references so ordering is correct
|
||||||
&ReferenceTransformer{},
|
&ReferenceTransformer{},
|
||||||
|
|
||||||
|
|
|
@ -82,15 +82,10 @@ func (b *EvalGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Add module variables
|
// Add module variables
|
||||||
&ModuleVariableTransformer{Config: b.Config},
|
&ModuleVariableTransformer{Config: b.Config},
|
||||||
|
|
||||||
// Must be run before TransformProviders so that resource configurations
|
|
||||||
// can be analyzed.
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
||||||
|
|
||||||
// Attach schema to the newly-created provider nodes.
|
// Must attach schemas before ReferenceTransformer so that we can
|
||||||
// (Will also redundantly re-attach schema to existing resource nodes,
|
// analyze the configuration to find references.
|
||||||
// but that's okay.)
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
&AttachSchemaTransformer{Schemas: b.Schemas},
|
||||||
|
|
||||||
// Connect so that the references are ready for targeting. We'll
|
// Connect so that the references are ready for targeting. We'll
|
||||||
|
|
|
@ -61,17 +61,8 @@ func (b *ImportGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Add root variables
|
// Add root variables
|
||||||
&RootVariableTransformer{Config: b.Config},
|
&RootVariableTransformer{Config: b.Config},
|
||||||
|
|
||||||
// Must be run before TransformProviders so that resource configurations
|
|
||||||
// can be analyzed.
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, config),
|
TransformProviders(b.Components.ResourceProviders(), concreteProvider, config),
|
||||||
|
|
||||||
// Attach schema to the newly-created provider nodes.
|
|
||||||
// (Will also redundantly re-attach schema to existing resource nodes,
|
|
||||||
// but that's okay.)
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
// This validates that the providers only depend on variables
|
// This validates that the providers only depend on variables
|
||||||
&ImportProviderValidateTransformer{},
|
&ImportProviderValidateTransformer{},
|
||||||
|
|
||||||
|
@ -84,6 +75,10 @@ func (b *ImportGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Add module variables
|
// Add module variables
|
||||||
&ModuleVariableTransformer{Config: b.Config},
|
&ModuleVariableTransformer{Config: b.Config},
|
||||||
|
|
||||||
|
// Must attach schemas before ReferenceTransformer so that we can
|
||||||
|
// analyze the configuration to find references.
|
||||||
|
&AttachSchemaTransformer{Schemas: b.Schemas},
|
||||||
|
|
||||||
// Connect so that the references are ready for targeting. We'll
|
// Connect so that the references are ready for targeting. We'll
|
||||||
// have to connect again later for providers and so on.
|
// have to connect again later for providers and so on.
|
||||||
&ReferenceTransformer{},
|
&ReferenceTransformer{},
|
||||||
|
|
|
@ -107,10 +107,6 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||||
|
|
||||||
&MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()},
|
&MissingProvisionerTransformer{Provisioners: b.Components.ResourceProvisioners()},
|
||||||
|
|
||||||
// Must be run before TransformProviders so that resource configurations
|
|
||||||
// can be analyzed.
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
// Add module variables
|
// Add module variables
|
||||||
&ModuleVariableTransformer{
|
&ModuleVariableTransformer{
|
||||||
Config: b.Config,
|
Config: b.Config,
|
||||||
|
@ -118,14 +114,13 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||||
|
|
||||||
TransformProviders(b.Components.ResourceProviders(), b.ConcreteProvider, b.Config),
|
TransformProviders(b.Components.ResourceProviders(), b.ConcreteProvider, b.Config),
|
||||||
|
|
||||||
// Attach schema to the newly-created provider nodes.
|
|
||||||
// (Will also redundantly re-attach schema to existing resource nodes,
|
|
||||||
// but that's okay.)
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
// Remove modules no longer present in the config
|
// Remove modules no longer present in the config
|
||||||
&RemovedModuleTransformer{Config: b.Config, State: b.State},
|
&RemovedModuleTransformer{Config: b.Config, State: b.State},
|
||||||
|
|
||||||
|
// Must attach schemas before ReferenceTransformer so that we can
|
||||||
|
// analyze the configuration to find references.
|
||||||
|
&AttachSchemaTransformer{Schemas: b.Schemas},
|
||||||
|
|
||||||
// Connect so that the references are ready for targeting. We'll
|
// Connect so that the references are ready for targeting. We'll
|
||||||
// have to connect again later for providers and so on.
|
// have to connect again later for providers and so on.
|
||||||
&ReferenceTransformer{},
|
&ReferenceTransformer{},
|
||||||
|
|
|
@ -99,7 +99,6 @@ aws_security_group.firewall
|
||||||
provider.aws
|
provider.aws
|
||||||
local.instance_id
|
local.instance_id
|
||||||
aws_instance.web
|
aws_instance.web
|
||||||
provider.aws
|
|
||||||
meta.count-boundary (count boundary fixup)
|
meta.count-boundary (count boundary fixup)
|
||||||
aws_instance.web
|
aws_instance.web
|
||||||
aws_load_balancer.weblb
|
aws_load_balancer.weblb
|
||||||
|
|
|
@ -138,15 +138,10 @@ func (b *RefreshGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Add module variables
|
// Add module variables
|
||||||
&ModuleVariableTransformer{Config: b.Config},
|
&ModuleVariableTransformer{Config: b.Config},
|
||||||
|
|
||||||
// Must be run before TransformProviders so that resource configurations
|
|
||||||
// can be analyzed.
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
|
||||||
|
|
||||||
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
TransformProviders(b.Components.ResourceProviders(), concreteProvider, b.Config),
|
||||||
|
|
||||||
// Attach schema to the newly-created provider nodes.
|
// Must attach schemas before ReferenceTransformer so that we can
|
||||||
// (Will also redundantly re-attach schema to existing resource nodes,
|
// analyze the configuration to find references.
|
||||||
// but that's okay.)
|
|
||||||
&AttachSchemaTransformer{Schemas: b.Schemas},
|
&AttachSchemaTransformer{Schemas: b.Schemas},
|
||||||
|
|
||||||
// Connect so that the references are ready for targeting. We'll
|
// Connect so that the references are ready for targeting. We'll
|
||||||
|
|
|
@ -149,15 +149,10 @@ func (t *DestroyEdgeTransformer) Transform(g *Graph) error {
|
||||||
&RootVariableTransformer{Config: t.Config},
|
&RootVariableTransformer{Config: t.Config},
|
||||||
&ModuleVariableTransformer{Config: t.Config},
|
&ModuleVariableTransformer{Config: t.Config},
|
||||||
|
|
||||||
// Must be run before TransformProviders so that resource configurations
|
|
||||||
// can be analyzed.
|
|
||||||
&AttachSchemaTransformer{Schemas: t.Schemas},
|
|
||||||
|
|
||||||
TransformProviders(nil, providerFn, t.Config),
|
TransformProviders(nil, providerFn, t.Config),
|
||||||
|
|
||||||
// Attach schema to the newly-created provider nodes.
|
// Must attach schemas before ReferenceTransformer so that we can
|
||||||
// (Will also redundantly re-attach schema to existing resource nodes,
|
// analyze the configuration to find references.
|
||||||
// but that's okay.)
|
|
||||||
&AttachSchemaTransformer{Schemas: t.Schemas},
|
&AttachSchemaTransformer{Schemas: t.Schemas},
|
||||||
|
|
||||||
&ReferenceTransformer{},
|
&ReferenceTransformer{},
|
||||||
|
|
|
@ -118,59 +118,6 @@ func (t *ProviderTransformer) Transform(g *Graph) error {
|
||||||
// Direct references need the provider configured as well as initialized
|
// Direct references need the provider configured as well as initialized
|
||||||
needConfigured[p.String()] = p
|
needConfigured[p.String()] = p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Does the vertex contain any references that need a provider to resolve?
|
|
||||||
if pv, ok := v.(GraphNodeReferencer); ok {
|
|
||||||
// Into which module does this vertex make references?
|
|
||||||
refPath := vertexReferencePath(v)
|
|
||||||
if _, exists := requested[v]; !exists {
|
|
||||||
requested[v] = make(map[string]ProviderRequest)
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
absRes := res.Absolute(refPath)
|
|
||||||
|
|
||||||
// Need to find the configuration of the resource we're
|
|
||||||
// referencing, to see which provider it belongs to.
|
|
||||||
if t.Config == nil {
|
|
||||||
log.Printf("[WARN] ProviderTransformer can't discover provider for %s: configuration not available", absRes)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
modConfig := t.Config.DescendentForInstance(refPath)
|
|
||||||
if modConfig == nil {
|
|
||||||
log.Printf("[WARN] ProviderTransformer can't discover provider for %s: no configuration for %s", absRes, refPath)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
rc := modConfig.Module.ResourceByAddr(res)
|
|
||||||
if rc == nil {
|
|
||||||
log.Printf("[WARN] ProviderTransformer can't discover provider for %s: resource configuration is not available", absRes)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
providerCfg := rc.ProviderConfigAddr().Absolute(refPath)
|
|
||||||
key := providerCfg.String()
|
|
||||||
log.Printf("[DEBUG] %s references %s, requiring %s", dag.VertexName(pv), absRes, key)
|
|
||||||
if _, exists := requested[v][key]; !exists {
|
|
||||||
requested[v][key] = ProviderRequest{
|
|
||||||
Addr: providerCfg,
|
|
||||||
Exact: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// No need to add to needConfigured here, because indirect
|
|
||||||
// references only need the provider initialized, not configured.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we'll go through all the requested addresses we just collected and
|
// Now we'll go through all the requested addresses we just collected and
|
||||||
|
|
Loading…
Reference in New Issue