diff --git a/terraform/eval_context_builtin.go b/terraform/eval_context_builtin.go index a0784af47f..1f890bb91a 100644 --- a/terraform/eval_context_builtin.go +++ b/terraform/eval_context_builtin.go @@ -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 diff --git a/terraform/eval_variable.go b/terraform/eval_variable.go index e8a88a14d3..d39c5d776f 100644 --- a/terraform/eval_variable.go +++ b/terraform/eval_variable.go @@ -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 diff --git a/terraform/node_module_variable.go b/terraform/node_module_variable.go index 103a91944b..ab0707a602 100644 --- a/terraform/node_module_variable.go +++ b/terraform/node_module_variable.go @@ -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, }, diff --git a/terraform/testdata/plan-modules-expand/main.tf b/terraform/testdata/plan-modules-expand/main.tf index 8cb4d96a9f..0e076491b3 100644 --- a/terraform/testdata/plan-modules-expand/main.tf +++ b/terraform/testdata/plan-modules-expand/main.tf @@ -10,10 +10,9 @@ variable "myvar" { default = "baz" } - module "count_child" { count = local.val - foo = 2 + foo = count.index bar = var.myvar source = "./child" }