diff --git a/internal/command/init2_test.go b/internal/command/init2_test.go index 815a0fe663..3d1a045a21 100644 --- a/internal/command/init2_test.go +++ b/internal/command/init2_test.go @@ -70,11 +70,7 @@ func TestInit2_dynamicSourceErrors(t *testing.T) { args: []string{"-get=false", "-var", "module_version=0.0.2"}, wantError: "Module version requirements have changed", }, - "provider function in const variable validation check": { - fixture: "provider-function-in-const-validation", - args: []string{"-var", "module_name=example"}, - wantError: "This happens if variable validation is\nbeing used on const variables during init.", - }, + "const variable with static validation check": { fixture: "const-var-source-with-validation", args: []string{"-var", "module_name=nonexistent"}, @@ -176,6 +172,13 @@ func TestInit2_dynamicSourceSuccess(t *testing.T) { // so the value will always be unknown regardless of input. args: []string{"-var", "const_var=hello"}, }, + + // The validation returns unknown during init, and must wait until + // a full validation is actually run. + "provider function in const variable validation check": { + fixture: "provider-function-in-const-validation", + args: []string{"-var", "module_name=example"}, + }, } for name, tc := range tests { diff --git a/internal/lang/eval.go b/internal/lang/eval.go index 6ae8702b0c..249c93d370 100644 --- a/internal/lang/eval.go +++ b/internal/lang/eval.go @@ -74,7 +74,7 @@ func (s *Scope) EvalBlock(body hcl.Body, schema *configschema.Block) (cty.Value, body = blocktoattr.FixUpBlockAttrs(body, schema) val, evalDiags := hcldec.Decode(body, spec, ctx) - diags = diags.Append(CheckForUnknownFunctionDiags(evalDiags, s.IgnoreUnknownProviderFunctions, false)) + diags = diags.Append(CheckForUnknownFunctionDiags(evalDiags, s.IgnoreUnknownProviderFunctions)) return val, diags } @@ -152,7 +152,7 @@ func (s *Scope) EvalSelfBlock(body hcl.Body, self cty.Value, schema *configschem } val, decDiags := hcldec.Decode(body, schema.DecoderSpec(), ctx) - diags = diags.Append(CheckForUnknownFunctionDiags(decDiags, s.IgnoreUnknownProviderFunctions, false)) + diags = diags.Append(CheckForUnknownFunctionDiags(decDiags, s.IgnoreUnknownProviderFunctions)) return val, diags } @@ -178,7 +178,7 @@ func (s *Scope) EvalExpr(expr hcl.Expression, wantType cty.Type) (cty.Value, tfd } val, evalDiags := expr.Value(ctx) - diags = diags.Append(CheckForUnknownFunctionDiags(evalDiags, s.IgnoreUnknownProviderFunctions, false)) + diags = diags.Append(CheckForUnknownFunctionDiags(evalDiags, s.IgnoreUnknownProviderFunctions)) if wantType != cty.DynamicPseudoType { var convErr error @@ -523,7 +523,7 @@ func normalizeRefValue(val cty.Value, diags tfdiags.Diagnostics) (cty.Value, tfd // namespace. The generic unknown function diagnostic from hcl does not direct // the user on how to remedy the situation in Terraform, and we can give more // useful information in a few Terraform specific cases here. -func CheckForUnknownFunctionDiags(diags hcl.Diagnostics, ignoreUnknownProviderFunctions bool, forbidProviderFunctions bool) hcl.Diagnostics { +func CheckForUnknownFunctionDiags(diags hcl.Diagnostics, ignoreUnknownProviderFunctions bool) hcl.Diagnostics { var filteredDiags hcl.Diagnostics for _, d := range diags { extra, ok := hcl.DiagnosticExtra[hclsyntax.FunctionCallUnknownDiagExtra](d) @@ -561,25 +561,9 @@ func CheckForUnknownFunctionDiags(diags hcl.Diagnostics, ignoreUnknownProviderFu // just get an unknown value result for any provider function calls, which is fine because // we won't have any provider functions available at this point anyway. if ignoreUnknownProviderFunctions { - - // For situations during init where provider functions could appear but are not valid, we need to keep - // the diagnostic, but we also add some info about why the function cannot be used in this context. - // - // Currently the only expressions that could encounter this situtation are validation blocks on constant variables. - if forbidProviderFunctions { - d.Detail = fmt.Sprintf("%s The function %q is not available because the provider namespace is "+ - "not populated in this context. This happens if variable validation is being used on const variables during init. "+ - "At this time we have neither downloaded nor initialized the provider, hence provider-defined functions are not usable and "+ - "should be removed from the validation block.", - d.Detail, namespace+"::"+name) - - filteredDiags = filteredDiags.Append(d) - } - continue - } else { - filteredDiags = filteredDiags.Append(d) } + filteredDiags = filteredDiags.Append(d) // the diagnostic isn't really shared with anything, and copying would // still retain the internal pointers, so we're going to modify the diff --git a/internal/terraform/eval_variable.go b/internal/terraform/eval_variable.go index 36880098f8..f300c2f044 100644 --- a/internal/terraform/eval_variable.go +++ b/internal/terraform/eval_variable.go @@ -333,7 +333,7 @@ func evalVariableValidation(validation *configs.CheckRule, hclCtx *hcl.EvalConte var diags tfdiags.Diagnostics result, moreDiags := validation.Condition.Value(hclCtx) - diags = diags.Append(lang.CheckForUnknownFunctionDiags(moreDiags, walkOp == walkInit, true)) + diags = diags.Append(lang.CheckForUnknownFunctionDiags(moreDiags, walkOp == walkInit)) errorValue, errorDiags := validation.ErrorMessage.Value(hclCtx) // The following error handling is a workaround to preserve backwards