add module expansion to validation
We cannot evaluate expansion during validation, since the values may not be known at that time. Inject a nodeValidateModule, using the "Concrete" pattern used for other node types during graph building. This node will always evaluate to a single module instance, so that we have a valid context within which to evaluate all sub resources.
This commit is contained in:
parent
5fda76e31d
commit
73492fd2d5
|
@ -52,6 +52,7 @@ type PlanGraphBuilder struct {
|
||||||
ConcreteProvider ConcreteProviderNodeFunc
|
ConcreteProvider ConcreteProviderNodeFunc
|
||||||
ConcreteResource ConcreteResourceNodeFunc
|
ConcreteResource ConcreteResourceNodeFunc
|
||||||
ConcreteResourceOrphan ConcreteResourceInstanceNodeFunc
|
ConcreteResourceOrphan ConcreteResourceInstanceNodeFunc
|
||||||
|
ConcreteModule ConcreteModuleNodeFunc
|
||||||
|
|
||||||
once sync.Once
|
once sync.Once
|
||||||
}
|
}
|
||||||
|
@ -140,7 +141,10 @@ func (b *PlanGraphBuilder) Steps() []GraphTransformer {
|
||||||
// Create expansion nodes for all of the module calls. This must
|
// Create expansion nodes for all of the module calls. This must
|
||||||
// come after all other transformers that create nodes representing
|
// come after all other transformers that create nodes representing
|
||||||
// objects that can belong to modules.
|
// objects that can belong to modules.
|
||||||
&ModuleExpansionTransformer{Config: b.Config},
|
&ModuleExpansionTransformer{
|
||||||
|
Concrete: b.ConcreteModule,
|
||||||
|
Config: b.Config,
|
||||||
|
},
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
|
@ -27,6 +27,12 @@ func ValidateGraphBuilder(p *PlanGraphBuilder) GraphBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.ConcreteModule = func(n *nodeExpandModule) dag.Vertex {
|
||||||
|
return &nodeValidateModule{
|
||||||
|
nodeExpandModule: *n,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We purposely don't set any other concrete types since they don't
|
// We purposely don't set any other concrete types since they don't
|
||||||
// require validation.
|
// require validation.
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/addrs"
|
"github.com/hashicorp/terraform/addrs"
|
||||||
"github.com/hashicorp/terraform/configs"
|
"github.com/hashicorp/terraform/configs"
|
||||||
|
"github.com/hashicorp/terraform/dag"
|
||||||
"github.com/hashicorp/terraform/lang"
|
"github.com/hashicorp/terraform/lang"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -14,6 +15,8 @@ type graphNodeModuleCloser interface {
|
||||||
CloseModule() addrs.Module
|
CloseModule() addrs.Module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ConcreteModuleNodeFunc func(n *nodeExpandModule) dag.Vertex
|
||||||
|
|
||||||
// nodeExpandModule represents a module call in the configuration that
|
// nodeExpandModule represents a module call in the configuration that
|
||||||
// might expand into multiple module instances depending on how it is
|
// might expand into multiple module instances depending on how it is
|
||||||
// configured.
|
// configured.
|
||||||
|
@ -214,3 +217,40 @@ func (n *evalPrepareModuleExpansion) Eval(ctx EvalContext) (interface{}, error)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nodeValidateModule wraps a nodeExpand module for validation, ensuring that
|
||||||
|
// no expansion is attempted during evaluation, when count and for_each
|
||||||
|
// expressions may not be known.
|
||||||
|
type nodeValidateModule struct {
|
||||||
|
nodeExpandModule
|
||||||
|
}
|
||||||
|
|
||||||
|
// GraphNodeEvalable
|
||||||
|
func (n *nodeValidateModule) EvalTree() EvalNode {
|
||||||
|
return &evalValidateModule{
|
||||||
|
Addr: n.Addr,
|
||||||
|
Config: n.Config,
|
||||||
|
ModuleCall: n.ModuleCall,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type evalValidateModule struct {
|
||||||
|
Addr addrs.Module
|
||||||
|
Config *configs.Module
|
||||||
|
ModuleCall *configs.ModuleCall
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *evalValidateModule) Eval(ctx EvalContext) (interface{}, error) {
|
||||||
|
_, call := n.Addr.Call()
|
||||||
|
expander := ctx.InstanceExpander()
|
||||||
|
|
||||||
|
// Modules all evaluate to single instances during validation, only to
|
||||||
|
// create a proper context within which to evaluate. All parent modules
|
||||||
|
// will be a single instance, but still get our address in the expected
|
||||||
|
// manner anyway to ensure they've been registered correctly.
|
||||||
|
for _, module := range expander.ExpandModule(n.Addr.Parent()) {
|
||||||
|
// now set our own mode to single
|
||||||
|
ctx.InstanceExpander().SetModuleSingle(module, call)
|
||||||
|
}
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,8 @@ import (
|
||||||
// This transform must be applied only after all nodes representing objects
|
// This transform must be applied only after all nodes representing objects
|
||||||
// that can be contained within modules have already been added.
|
// that can be contained within modules have already been added.
|
||||||
type ModuleExpansionTransformer struct {
|
type ModuleExpansionTransformer struct {
|
||||||
Config *configs.Config
|
Config *configs.Config
|
||||||
|
Concrete ConcreteModuleNodeFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *ModuleExpansionTransformer) Transform(g *Graph) error {
|
func (t *ModuleExpansionTransformer) Transform(g *Graph) error {
|
||||||
|
@ -36,11 +37,16 @@ func (t *ModuleExpansionTransformer) transform(g *Graph, c *configs.Config, pare
|
||||||
_, call := c.Path.Call()
|
_, call := c.Path.Call()
|
||||||
modCall := c.Parent.Module.ModuleCalls[call.Name]
|
modCall := c.Parent.Module.ModuleCalls[call.Name]
|
||||||
|
|
||||||
v := &nodeExpandModule{
|
n := &nodeExpandModule{
|
||||||
Addr: c.Path,
|
Addr: c.Path,
|
||||||
Config: c.Module,
|
Config: c.Module,
|
||||||
ModuleCall: modCall,
|
ModuleCall: modCall,
|
||||||
}
|
}
|
||||||
|
var v dag.Vertex = n
|
||||||
|
if t.Concrete != nil {
|
||||||
|
v = t.Concrete(n)
|
||||||
|
}
|
||||||
|
|
||||||
g.Add(v)
|
g.Add(v)
|
||||||
log.Printf("[TRACE] ModuleExpansionTransformer: Added %s as %T", c.Path, v)
|
log.Printf("[TRACE] ModuleExpansionTransformer: Added %s as %T", c.Path, v)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue