diff --git a/internal/terraform/eval_for_each.go b/internal/terraform/eval_for_each.go index 630dc9c724..d605f127ec 100644 --- a/internal/terraform/eval_for_each.go +++ b/internal/terraform/eval_for_each.go @@ -90,6 +90,7 @@ func (ev *forEachEvaluator) ResourceValue() (map[string]cty.Value, bool, tfdiags return res, false, diags } + forEachVal = marks.RemoveDeprecationMarks(forEachVal) if forEachVal.IsNull() || !forEachVal.IsKnown() || markSafeLengthInt(forEachVal) == 0 { // we check length, because an empty set returns a nil map which will panic below return res, true, diags diff --git a/internal/terraform/node_action_instance.go b/internal/terraform/node_action_instance.go index cfcc89338d..4687120d9d 100644 --- a/internal/terraform/node_action_instance.go +++ b/internal/terraform/node_action_instance.go @@ -71,7 +71,10 @@ func (n *NodeActionDeclarationInstance) Execute(ctx EvalContext, _ walkOperation valDiags := validateResourceForbiddenEphemeralValues(ctx, configVal, n.Schema.ConfigSchema) diags = diags.Append(valDiags.InConfigBody(n.Config.Config, n.Addr.String())) - if valDiags.HasErrors() { + deprecationDiags := ctx.Deprecations().ValidateAsConfig(configVal, n.ModulePath()) + diags = diags.Append(deprecationDiags.InConfigBody(n.Config.Config, n.Addr.String())) + + if diags.HasErrors() { return diags } } diff --git a/internal/terraform/node_action_partialexp.go b/internal/terraform/node_action_partialexp.go index f1abe3e20f..69478d6873 100644 --- a/internal/terraform/node_action_partialexp.go +++ b/internal/terraform/node_action_partialexp.go @@ -68,6 +68,12 @@ func (n *NodeActionDeclarationPartialExpanded) Execute(ctx EvalContext, op walkO if diags.HasErrors() { return diags } + + deprecationDiags := ctx.Deprecations().ValidateAsConfig(configVal, n.ActionAddr().Module) + diags = diags.Append(deprecationDiags) + if diags.HasErrors() { + return diags + } } ctx.Actions().AddPartialExpandedAction(n.addr, configVal, n.resolvedProvider) return nil diff --git a/internal/terraform/node_action_validate.go b/internal/terraform/node_action_validate.go index 47041abd62..bbf79f86ee 100644 --- a/internal/terraform/node_action_validate.go +++ b/internal/terraform/node_action_validate.go @@ -107,6 +107,10 @@ func (n *NodeValidatableAction) Execute(ctx EvalContext, _ walkOperation) tfdiag valDiags = validateResourceForbiddenEphemeralValues(ctx, configVal, schema.ConfigSchema) diags = diags.Append(valDiags.InConfigBody(config, n.Addr.String())) + if diags.HasErrors() { + return diags + } + // Use unmarked value for validate request unmarkedConfigVal, _ := configVal.UnmarkDeep() log.Printf("[TRACE] Validating config for %q", n.Addr) diff --git a/internal/terraform/node_local.go b/internal/terraform/node_local.go index 171e96b3ac..c0edab0033 100644 --- a/internal/terraform/node_local.go +++ b/internal/terraform/node_local.go @@ -237,5 +237,10 @@ func evaluateLocalValue(config *configs.Local, localAddr addrs.LocalValue, addrS if val == cty.NilVal { val = cty.DynamicVal } + + var deprecationDiags tfdiags.Diagnostics + val, deprecationDiags = ctx.Deprecations().Validate(val, ctx.Path().Module(), expr.Range().Ptr()) + diags = diags.Append(deprecationDiags) + return val, diags } diff --git a/internal/terraform/node_local_test.go b/internal/terraform/node_local_test.go index b3ed692cde..9c640ebfc4 100644 --- a/internal/terraform/node_local_test.go +++ b/internal/terraform/node_local_test.go @@ -59,8 +59,11 @@ func TestNodeLocalExecute(t *testing.T) { EvaluateExprResult: test.Want, } + scopedCtx := ctx.withScope(evalContextModuleInstance{ + Addr: addrs.RootModuleInstance, + }) - err := n.Execute(ctx, walkApply) + err := n.Execute(scopedCtx, walkApply) if (err != nil) != test.Err { if err != nil { t.Errorf("unexpected error: %s", err) diff --git a/internal/terraform/node_provider.go b/internal/terraform/node_provider.go index e691451c46..0b05761209 100644 --- a/internal/terraform/node_provider.go +++ b/internal/terraform/node_provider.go @@ -78,10 +78,16 @@ func (n *NodeApplyableProvider) ValidateProvider(ctx EvalContext, provider provi } configVal, _, evalDiags := ctx.EvaluateBlock(configBody, configSchema, nil, EvalDataForNoInstanceKey) - if evalDiags.HasErrors() { - return diags.Append(evalDiags) - } diags = diags.Append(evalDiags) + if diags.HasErrors() { + return diags + } + + deprecationDiags := ctx.Deprecations().ValidateAsConfig(configVal, n.Addr.Module) + diags = diags.Append(deprecationDiags.InConfigBody(configBody, n.Addr.String())) + if diags.HasErrors() { + return diags + } // If our config value contains any marked values, ensure those are // stripped out before sending this to the provider diff --git a/internal/terraform/node_resource_abstract_instance.go b/internal/terraform/node_resource_abstract_instance.go index 3f38599dba..875b925f56 100644 --- a/internal/terraform/node_resource_abstract_instance.go +++ b/internal/terraform/node_resource_abstract_instance.go @@ -1787,6 +1787,10 @@ func (n *NodeAbstractResourceInstance) providerMetas(ctx EvalContext) (cty.Value var configDiags tfdiags.Diagnostics metaConfigVal, _, configDiags = ctx.EvaluateBlock(m.Config, providerSchema.ProviderMeta.Body, nil, EvalDataForNoInstanceKey) diags = diags.Append(configDiags) + diags = diags.Append( + ctx.Deprecations().ValidateAsConfig(metaConfigVal, ctx.Path().Module()).InConfigBody(m.Config, n.Addr.String()), + ) + metaConfigVal = marks.RemoveDeprecationMarks(metaConfigVal) } } } @@ -1863,6 +1867,10 @@ func (n *NodeAbstractResourceInstance) planDataSource(ctx EvalContext, checkRule diags = diags.Append( validateResourceForbiddenEphemeralValues(ctx, configVal, schema.Body).InConfigBody(n.Config.Config, n.Addr.String()), ) + diags = diags.Append( + ctx.Deprecations().ValidateAsConfig(configVal, ctx.Path().Module()).InConfigBody(n.Config.Config, n.Addr.String()), + ) + configVal = marks.RemoveDeprecationMarks(configVal) if diags.HasErrors() { return nil, nil, deferred, keyData, diags } @@ -2200,6 +2208,14 @@ func (n *NodeAbstractResourceInstance) applyDataSource(ctx EvalContext, planned return nil, keyData, diags } + diags = diags.Append( + ctx.Deprecations().ValidateAsConfig(configVal, n.ModulePath()).InConfigBody(n.Config.Config, n.Addr.String()), + ) + if diags.HasErrors() { + return nil, keyData, diags + } + configVal = marks.RemoveDeprecationMarks(configVal) + newVal, readDeferred, readDiags := n.readDataSource(ctx, configVal) if check, nested := n.nestedInCheckBlock(); nested { addr := check.Addr().Absolute(n.Addr.Module) @@ -2511,6 +2527,8 @@ func (n *NodeAbstractResourceInstance) evalProvisionerConfig(ctx EvalContext, bo config, _, configDiags := ctx.EvaluateBlock(body, schema, n.ResourceInstanceAddr().Resource, keyData) diags = diags.Append(configDiags) + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(config, n.ModulePath()).InConfigBody(body, n.Addr.String())) + config = marks.RemoveDeprecationMarks(config) return config, diags } @@ -2528,7 +2546,8 @@ func (n *NodeAbstractResourceInstance) evalDestroyProvisionerConfig(ctx EvalCont evalScope := ctx.EvaluationScope(n.ResourceInstanceAddr().Resource, nil, keyData) config, evalDiags := evalScope.EvalSelfBlock(body, self, schema, keyData) diags = diags.Append(evalDiags) - + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(config, n.ModulePath()).InConfigBody(body, n.Addr.String())) + config = marks.RemoveDeprecationMarks(config) return config, diags } diff --git a/internal/terraform/node_resource_ephemeral.go b/internal/terraform/node_resource_ephemeral.go index 7910326978..9823b88243 100644 --- a/internal/terraform/node_resource_ephemeral.go +++ b/internal/terraform/node_resource_ephemeral.go @@ -76,6 +76,11 @@ func ephemeralResourceOpen(ctx EvalContext, inp ephemeralResourceInput) (*provid if diags.HasErrors() { return nil, diags } + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(configVal, ctx.Path().Module()).InConfigBody(config.Config, inp.addr.String())) + if diags.HasErrors() { + return nil, diags + } + unmarkedConfigVal, configMarks := configVal.UnmarkDeepWithPaths() if !unmarkedConfigVal.IsWhollyKnown() { diff --git a/internal/terraform/node_resource_plan_instance.go b/internal/terraform/node_resource_plan_instance.go index ff700b201c..c9b1215072 100644 --- a/internal/terraform/node_resource_plan_instance.go +++ b/internal/terraform/node_resource_plan_instance.go @@ -662,6 +662,11 @@ func (n *NodePlannableResourceInstance) importState(ctx EvalContext, addr addrs. diags = diags.Append(configDiags) return nil, deferred, diags } + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(configVal, n.ModulePath()).InConfigBody(n.Config.Config, absAddr.String())) + if diags.HasErrors() { + return nil, deferred, diags + } + configVal, _ = configVal.UnmarkDeep() // Let's pretend we're reading the value as a data source so we diff --git a/internal/terraform/node_resource_plan_instance_query.go b/internal/terraform/node_resource_plan_instance_query.go index 6e099b14f7..3421765adf 100644 --- a/internal/terraform/node_resource_plan_instance_query.go +++ b/internal/terraform/node_resource_plan_instance_query.go @@ -8,6 +8,7 @@ import ( "log" "github.com/hashicorp/terraform/internal/addrs" + "github.com/hashicorp/terraform/internal/lang/marks" "github.com/hashicorp/terraform/internal/plans" "github.com/hashicorp/terraform/internal/providers" "github.com/hashicorp/terraform/internal/tfdiags" @@ -50,6 +51,11 @@ func (n *NodePlannableResourceInstance) listResourceExecute(ctx EvalContext) (di return diags } + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(blockVal, n.ModulePath()).InConfigBody(config.Config, n.Addr.String())) + if diags.HasErrors() { + return diags + } + // Unmark before sending to provider unmarkedBlockVal, _ := blockVal.UnmarkDeepWithPaths() configKnown := blockVal.IsWhollyKnown() @@ -64,12 +70,26 @@ func (n *NodePlannableResourceInstance) listResourceExecute(ctx EvalContext) (di return diags } + if config.List.Limit != nil { + var limitDeprecationDiags tfdiags.Diagnostics + limitCty, limitDeprecationDiags = ctx.Deprecations().Validate(limitCty, ctx.Path().Module(), config.List.Limit.Range().Ptr()) + diags = diags.Append(limitDeprecationDiags) + limitCty = marks.RemoveDeprecationMarks(limitCty) + } + includeRscCty, includeRsc, includeDiags := newIncludeRscEvaluator(false).EvaluateExpr(ctx, config.List.IncludeResource) diags = diags.Append(includeDiags) if includeDiags.HasErrors() { return diags } + if config.List.IncludeResource != nil { + var includeDeprecationDiags tfdiags.Diagnostics + includeRscCty, includeDeprecationDiags = ctx.Deprecations().Validate(includeRscCty, ctx.Path().Module(), config.List.IncludeResource.Range().Ptr()) + diags = diags.Append(includeDeprecationDiags) + includeRscCty = marks.RemoveDeprecationMarks(includeRscCty) + } + rId := HookResourceIdentity{ Addr: addr, ProviderAddr: n.ResolvedProvider.Provider, diff --git a/internal/terraform/node_resource_plan_partialexp.go b/internal/terraform/node_resource_plan_partialexp.go index d2675b0449..048d15923a 100644 --- a/internal/terraform/node_resource_plan_partialexp.go +++ b/internal/terraform/node_resource_plan_partialexp.go @@ -200,6 +200,11 @@ func (n *nodePlannablePartialExpandedResource) managedResourceExecute(ctx EvalCo return &change, diags } + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(configVal, n.ResourceAddr().Module).InConfigBody(n.config.Config, n.addr.String())) + if diags.HasErrors() { + return &change, diags + } + unmarkedConfigVal, _ := configVal.UnmarkDeep() log.Printf("[TRACE] Validating partially expanded config for %q", n.addr) validateResp := provider.ValidateResourceConfig( @@ -354,6 +359,11 @@ func (n *nodePlannablePartialExpandedResource) dataResourceExecute(ctx EvalConte return &change, diags } + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(configVal, n.ResourceAddr().Module).InConfigBody(n.config.Config, n.addr.String())) + if diags.HasErrors() { + return &change, diags + } + // Note: We're deliberately not doing anything special for nested-in-a-check // data sources. (*NodeAbstractResourceInstance).planDataSource has some // special handling for these, but it's founded on the assumption that we're diff --git a/internal/terraform/node_resource_validate.go b/internal/terraform/node_resource_validate.go index 603a264793..8028dd1e5c 100644 --- a/internal/terraform/node_resource_validate.go +++ b/internal/terraform/node_resource_validate.go @@ -19,6 +19,7 @@ import ( "github.com/hashicorp/terraform/internal/lang/ephemeral" "github.com/hashicorp/terraform/internal/lang/format" "github.com/hashicorp/terraform/internal/lang/langrefs" + "github.com/hashicorp/terraform/internal/lang/marks" "github.com/hashicorp/terraform/internal/providers" "github.com/hashicorp/terraform/internal/provisioners" "github.com/hashicorp/terraform/internal/tfdiags" @@ -142,7 +143,10 @@ func (n *NodeValidatableResource) validateProvisioner(ctx EvalContext, p *config func (n *NodeValidatableResource) evaluateBlock(ctx EvalContext, body hcl.Body, schema *configschema.Block) (cty.Value, hcl.Body, tfdiags.Diagnostics) { keyData, selfAddr := n.stubRepetitionData(n.Config.Count != nil, n.Config.ForEach != nil) - return ctx.EvaluateBlock(body, schema, selfAddr, keyData) + val, hclBody, diags := ctx.EvaluateBlock(body, schema, selfAddr, keyData) + diags = diags.Append(ctx.Deprecations().ValidateAsConfig(val, n.Addr.Module).InConfigBody(body, n.Addr.String())) + + return marks.RemoveDeprecationMarks(val), hclBody, diags } // connectionBlockSupersetSchema is a schema representing the superset of all @@ -464,6 +468,9 @@ func (n *NodeValidatableResource) validateResource(ctx EvalContext) tfdiags.Diag if valDiags.HasErrors() { return diags } + diags = diags.Append( + ctx.Deprecations().ValidateAsConfig(configVal, n.ModulePath()).InConfigBody(n.Config.Config, n.Addr.String()), + ) // Use unmarked value for validate request unmarkedConfigVal, _ := configVal.UnmarkDeep() req := providers.ValidateEphemeralResourceConfigRequest{ @@ -498,14 +505,24 @@ func (n *NodeValidatableResource) validateResource(ctx EvalContext) tfdiags.Diag if limitDiags.HasErrors() { return diags } - diags = diags.Append(ctx.Deprecations().ValidateAsConfig(limit, n.ModulePath())) + if n.Config.List.Limit != nil { + var limitDeprecationDiags tfdiags.Diagnostics + limit, limitDeprecationDiags = ctx.Deprecations().Validate(limit, n.ModulePath(), n.Config.List.Limit.Range().Ptr()) + diags = diags.Append(limitDeprecationDiags) + limit = marks.RemoveDeprecationMarks(limit) + } includeResource, _, includeDiags := newIncludeRscEvaluator(true).EvaluateExpr(ctx, n.Config.List.IncludeResource) diags = diags.Append(includeDiags) if includeDiags.HasErrors() { return diags } - diags = diags.Append(ctx.Deprecations().ValidateAsConfig(includeResource, n.ModulePath())) + if n.Config.List.IncludeResource != nil { + var includeDeprecationDiags tfdiags.Diagnostics + includeResource, includeDeprecationDiags = ctx.Deprecations().Validate(includeResource, n.ModulePath(), n.Config.List.IncludeResource.Range().Ptr()) + diags = diags.Append(includeDeprecationDiags) + includeResource = marks.RemoveDeprecationMarks(includeResource) + } // Use unmarked value for validate request unmarkedBlockVal, _ := blockVal.UnmarkDeep()