From 3cf84bb3f979de01c9809a859cfb06ccfe2fc14c Mon Sep 17 00:00:00 2001 From: James Bardin Date: Thu, 6 Aug 2020 22:25:46 -0400 Subject: [PATCH] don't add state to the validate context The validate command should work with the configuration, but when validate was run at the start of a plan or apply command the state was inserted in preparation for the next walk. This could lead to errors when the resource schemas had changes and the state could not be upgraded or decoded. --- backend/local/backend_local.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/backend/local/backend_local.go b/backend/local/backend_local.go index 4fffc5b66..312456207 100644 --- a/backend/local/backend_local.go +++ b/backend/local/backend_local.go @@ -72,6 +72,13 @@ func (b *Local) context(op *backend.Operation) (*terraform.Context, *configload. log.Printf("[TRACE] backend/local: retrieving local state snapshot for workspace %q", op.Workspace) opts.State = s.State() + // Prepare a separate opts and context for validation, which doesn't use + // any state ensuring that we only validate the config, since evaluation + // will automatically reference the state when available. + validateOpts := opts + validateOpts.State = nil + var validateCtx *terraform.Context + var tfCtx *terraform.Context var ctxDiags tfdiags.Diagnostics var configSnap *configload.Snapshot @@ -89,9 +96,18 @@ func (b *Local) context(op *backend.Operation) (*terraform.Context, *configload. // Write sources into the cache of the main loader so that they are // available if we need to generate diagnostic message snippets. op.ConfigLoader.ImportSourcesFromSnapshot(configSnap) + + // create a validation context with no state + validateCtx, _, _ = b.contextFromPlanFile(op.PlanFile, validateOpts, stateMeta) + // diags from here will be caught above + } else { log.Printf("[TRACE] backend/local: building context for current working directory") tfCtx, configSnap, ctxDiags = b.contextDirect(op, opts) + + // create a validation context with no state + validateCtx, _, _ = b.contextDirect(op, validateOpts) + // diags from here will be caught above } diags = diags.Append(ctxDiags) if diags.HasErrors() { @@ -117,7 +133,7 @@ func (b *Local) context(op *backend.Operation) (*terraform.Context, *configload. // If validation is enabled, validate if b.OpValidation { log.Printf("[TRACE] backend/local: running validation operation") - validateDiags := tfCtx.Validate() + validateDiags := validateCtx.Validate() diags = diags.Append(validateDiags) } }