diff --git a/eval_context.go b/eval_context.go index 915910ad..e0822b7b 100644 --- a/eval_context.go +++ b/eval_context.go @@ -11,6 +11,10 @@ type EvalContext struct { Variables map[string]cty.Value Functions map[string]function.Function parent *EvalContext + + // UnknownVariable handles when an unknown variable is referenced. + // This handler is experimental and may change in the future. + UnknownVariable func(Traversal) (cty.Value, error) } // NewChild returns a new EvalContext that is a child of the receiver. diff --git a/traversal.go b/traversal.go index d7101970..cd66be59 100644 --- a/traversal.go +++ b/traversal.go @@ -70,7 +70,12 @@ func (t Traversal) TraverseAbs(ctx *EvalContext) (cty.Value, Diagnostics) { thisCtx := ctx hasNonNil := false + var unknownHandler func(Traversal) (cty.Value, error) for thisCtx != nil { + if unknownHandler == nil && thisCtx.UnknownVariable != nil { + unknownHandler = thisCtx.UnknownVariable + } + if thisCtx.Variables == nil { thisCtx = thisCtx.parent continue @@ -83,6 +88,13 @@ func (t Traversal) TraverseAbs(ctx *EvalContext) (cty.Value, Diagnostics) { thisCtx = thisCtx.parent } + if unknownHandler != nil { + v, err := unknownHandler(t) + if err == nil { + return v, nil + } + } + if !hasNonNil { return cty.DynamicVal, Diagnostics{ {