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 // pathSet indicates that this context was explicitly created for a
// specific path, and can be safely used for evaluation. This lets us // 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 // equivalent to RootModuleInstance. Path and Evaluation methods will
// panic if this is not set. // panic if this is not set.
pathSet bool pathSet bool

View File

@ -40,6 +40,7 @@ type EvalModuleCallArgument struct {
Addr addrs.InputVariable Addr addrs.InputVariable
Config *configs.Variable Config *configs.Variable
Expr hcl.Expression Expr hcl.Expression
ModuleInstance addrs.ModuleInstance
// If this flag is set, any diagnostics are discarded and this operation // If this flag is set, any diagnostics are discarded and this operation
// will always succeed, though may produce an unknown value in the // 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 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 // We intentionally passed DynamicPseudoType to EvaluateExpr above because
// now we can do our own local type conversion and produce an error message // now we can do our own local type conversion and produce an error message

View File

@ -41,6 +41,7 @@ func (n *NodePlannableModuleVariable) DynamicExpand(ctx EvalContext) (*Graph, er
Addr: n.Addr.Absolute(module), Addr: n.Addr.Absolute(module),
Config: n.Config, Config: n.Config,
Expr: n.Expr, Expr: n.Expr,
ModuleInstance: module,
} }
g.Add(o) g.Add(o)
} }
@ -114,6 +115,9 @@ type NodeApplyableModuleVariable struct {
Addr addrs.AbsInputVariableInstance Addr addrs.AbsInputVariableInstance
Config *configs.Variable // Config is the var in the config Config *configs.Variable // Config is the var in the config
Expr hcl.Expression // Expr is the value expression given in the call 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 // Ensure that we are implementing all of the interfaces we think we are
@ -220,11 +224,12 @@ func (n *NodeApplyableModuleVariable) EvalTree() EvalNode {
Nodes: []EvalNode{ Nodes: []EvalNode{
&EvalOpFilter{ &EvalOpFilter{
Ops: []walkOperation{walkRefresh, walkPlan, walkApply, Ops: []walkOperation{walkRefresh, walkPlan, walkApply,
walkDestroy, walkValidate}, walkDestroy},
Node: &EvalModuleCallArgument{ Node: &EvalModuleCallArgument{
Addr: n.Addr.Variable, Addr: n.Addr.Variable,
Config: n.Config, Config: n.Config,
Expr: n.Expr, Expr: n.Expr,
ModuleInstance: n.ModuleInstance,
Values: vals, Values: vals,
IgnoreDiagnostics: false, IgnoreDiagnostics: false,

View File

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