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:
Martin Atkins 2018-06-01 13:00:52 -07:00
parent d3e4565681
commit 71cedf19a4
8 changed files with 18 additions and 102 deletions

View File

@ -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{},

View File

@ -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

View File

@ -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{},

View File

@ -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{},

View File

@ -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

View File

@ -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

View File

@ -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{},

View File

@ -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