Evaluate ModuleCallArguments using the appropriate ModuleInstance scope

This commit is contained in:
Pam Selle 2020-04-03 15:28:04 -04:00
parent bc3de6e2d6
commit 57c26fc11b
4 changed files with 24 additions and 15 deletions

View File

@ -34,7 +34,7 @@ type BuiltinEvalContext struct {
// pathSet indicates that this context was explicitly created for a
// specific path, and can be safely used for evaluation. This lets us
// differentiate between Pathvalue being unset, and the zero value which is
// differentiate between PathValue being unset, and the zero value which is
// equivalent to RootModuleInstance. Path and Evaluation methods will
// panic if this is not set.
pathSet bool

View File

@ -37,9 +37,10 @@ func (n *EvalSetModuleCallArguments) Eval(ctx EvalContext) (interface{}, error)
// EvalContext.SetModuleCallArguments, which expects a map to merge in with
// any existing arguments.
type EvalModuleCallArgument struct {
Addr addrs.InputVariable
Config *configs.Variable
Expr hcl.Expression
Addr addrs.InputVariable
Config *configs.Variable
Expr hcl.Expression
ModuleInstance addrs.ModuleInstance
// If this flag is set, any diagnostics are discarded and this operation
// will always succeed, though may produce an unknown value in the
@ -68,7 +69,11 @@ func (n *EvalModuleCallArgument) Eval(ctx EvalContext) (interface{}, error) {
return nil, nil
}
val, diags := ctx.EvaluateExpr(expr, cty.DynamicPseudoType, nil)
// Get the repetition data for this module instance,
// so we can create the appropriate scope for evaluating our expression
moduleInstanceRepetitionData := ctx.InstanceExpander().GetModuleInstanceRepetitionData(n.ModuleInstance)
scope := ctx.EvaluationScope(nil, moduleInstanceRepetitionData)
val, diags := scope.EvalExpr(expr, cty.DynamicPseudoType)
// We intentionally passed DynamicPseudoType to EvaluateExpr above because
// now we can do our own local type conversion and produce an error message

View File

@ -38,9 +38,10 @@ func (n *NodePlannableModuleVariable) DynamicExpand(ctx EvalContext) (*Graph, er
expander := ctx.InstanceExpander()
for _, module := range expander.ExpandModule(n.Module) {
o := &NodeApplyableModuleVariable{
Addr: n.Addr.Absolute(module),
Config: n.Config,
Expr: n.Expr,
Addr: n.Addr.Absolute(module),
Config: n.Config,
Expr: n.Expr,
ModuleInstance: module,
}
g.Add(o)
}
@ -114,6 +115,9 @@ type NodeApplyableModuleVariable struct {
Addr addrs.AbsInputVariableInstance
Config *configs.Variable // Config is the var in the config
Expr hcl.Expression // Expr is the value expression given in the call
// ModuleInstance in order to create the appropriate context for evaluating
// ModuleCallArguments, ex. so count.index and each.key can resolve
ModuleInstance addrs.ModuleInstance
}
// Ensure that we are implementing all of the interfaces we think we are
@ -220,12 +224,13 @@ func (n *NodeApplyableModuleVariable) EvalTree() EvalNode {
Nodes: []EvalNode{
&EvalOpFilter{
Ops: []walkOperation{walkRefresh, walkPlan, walkApply,
walkDestroy, walkValidate},
walkDestroy},
Node: &EvalModuleCallArgument{
Addr: n.Addr.Variable,
Config: n.Config,
Expr: n.Expr,
Values: vals,
Addr: n.Addr.Variable,
Config: n.Config,
Expr: n.Expr,
ModuleInstance: n.ModuleInstance,
Values: vals,
IgnoreDiagnostics: false,
},

View File

@ -10,10 +10,9 @@ variable "myvar" {
default = "baz"
}
module "count_child" {
count = local.val
foo = 2
foo = count.index
bar = var.myvar
source = "./child"
}