|
|
|
|
@ -5,8 +5,8 @@ import (
|
|
|
|
|
|
|
|
|
|
"github.com/hashicorp/terraform/addrs"
|
|
|
|
|
"github.com/hashicorp/terraform/configs"
|
|
|
|
|
"github.com/hashicorp/terraform/dag"
|
|
|
|
|
"github.com/hashicorp/terraform/lang"
|
|
|
|
|
"github.com/hashicorp/terraform/states"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// graphNodeModuleCloser is an interface implemented by nodes that finalize the
|
|
|
|
|
@ -15,6 +15,8 @@ type graphNodeModuleCloser interface {
|
|
|
|
|
CloseModule() addrs.Module
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type ConcreteModuleNodeFunc func(n *nodeExpandModule) dag.Vertex
|
|
|
|
|
|
|
|
|
|
// nodeExpandModule represents a module call in the configuration that
|
|
|
|
|
// might expand into multiple module instances depending on how it is
|
|
|
|
|
// configured.
|
|
|
|
|
@ -184,9 +186,7 @@ type evalPrepareModuleExpansion struct {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (n *evalPrepareModuleExpansion) Eval(ctx EvalContext) (interface{}, error) {
|
|
|
|
|
eachMode := states.NoEach
|
|
|
|
|
expander := ctx.InstanceExpander()
|
|
|
|
|
|
|
|
|
|
_, call := n.Addr.Call()
|
|
|
|
|
|
|
|
|
|
// nodeExpandModule itself does not have visibility into how its ancestors
|
|
|
|
|
@ -194,29 +194,22 @@ func (n *evalPrepareModuleExpansion) Eval(ctx EvalContext) (interface{}, error)
|
|
|
|
|
// to our module, and register module instances with each of them.
|
|
|
|
|
for _, module := range expander.ExpandModule(n.Addr.Parent()) {
|
|
|
|
|
ctx = ctx.WithPath(module)
|
|
|
|
|
count, countDiags := evaluateResourceCountExpression(n.ModuleCall.Count, ctx)
|
|
|
|
|
if countDiags.HasErrors() {
|
|
|
|
|
return nil, countDiags.Err()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if count >= 0 { // -1 signals "count not set"
|
|
|
|
|
eachMode = states.EachList
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
forEach, forEachDiags := evaluateResourceForEachExpression(n.ModuleCall.ForEach, ctx)
|
|
|
|
|
if forEachDiags.HasErrors() {
|
|
|
|
|
return nil, forEachDiags.Err()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if forEach != nil {
|
|
|
|
|
eachMode = states.EachMap
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch eachMode {
|
|
|
|
|
case states.EachList:
|
|
|
|
|
switch {
|
|
|
|
|
case n.ModuleCall.Count != nil:
|
|
|
|
|
count, diags := evaluateResourceCountExpression(n.ModuleCall.Count, ctx)
|
|
|
|
|
if diags.HasErrors() {
|
|
|
|
|
return nil, diags.Err()
|
|
|
|
|
}
|
|
|
|
|
expander.SetModuleCount(module, call, count)
|
|
|
|
|
case states.EachMap:
|
|
|
|
|
|
|
|
|
|
case n.ModuleCall.ForEach != nil:
|
|
|
|
|
forEach, diags := evaluateResourceForEachExpression(n.ModuleCall.ForEach, ctx)
|
|
|
|
|
if diags.HasErrors() {
|
|
|
|
|
return nil, diags.Err()
|
|
|
|
|
}
|
|
|
|
|
expander.SetModuleForEach(module, call, forEach)
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
expander.SetModuleSingle(module, call)
|
|
|
|
|
}
|
|
|
|
|
@ -224,3 +217,40 @@ func (n *evalPrepareModuleExpansion) Eval(ctx EvalContext) (interface{}, error)
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|