From 2bab5bf502d1f958343f8cec142c460cc4a19388 Mon Sep 17 00:00:00 2001 From: Martin Atkins Date: Tue, 25 Sep 2018 17:38:16 -0700 Subject: [PATCH] core: Allow planned Update change to become NoOp during apply This can happen if unknown values in the plan actually end up being identical to the prior values once resolved. In that case, we'll just make no change at all. This is verified by TestContext2Apply_ignoreChangesWithDep. --- terraform/context_apply_test.go | 9 +++------ terraform/eval_diff.go | 26 +++++++++++++++++--------- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/terraform/context_apply_test.go b/terraform/context_apply_test.go index af3fc4fe4..0fc33f699 100644 --- a/terraform/context_apply_test.go +++ b/terraform/context_apply_test.go @@ -8959,14 +8959,11 @@ func TestContext2Apply_ignoreChangesWithDep(t *testing.T) { State: s, }) - if _, diags := ctx.Plan(); diags.HasErrors() { - t.Fatalf("plan errors: %s", diags.Err()) - } + _, diags := ctx.Plan() + assertNoErrors(t, diags) state, diags := ctx.Apply() - if diags.HasErrors() { - t.Fatalf("diags: %s", diags.Err()) - } + assertNoErrors(t, diags) actual := strings.TrimSpace(state.String()) expected := strings.TrimSpace(s.String()) diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index b94e25cd8..6f0dccfb4 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -56,15 +56,23 @@ func (n *EvalCheckPlannedChange) Eval(ctx EvalContext) (interface{}, error) { log.Printf("[TRACE] EvalCheckPlannedChange: Verifying that actual change (action %s) matches planned change (action %s)", actualChange.Action, plannedChange.Action) if plannedChange.Action != actualChange.Action { - diags = diags.Append(tfdiags.Sourceless( - tfdiags.Error, - "Provider produced inconsistent final plan", - fmt.Sprintf( - "When expanding the plan for %s to include new values learned so far during apply, provider %q changed the planned action from %s to %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", - absAddr, n.ProviderAddr.ProviderConfig.Type, - plannedChange.Action, actualChange.Action, - ), - )) + switch { + case plannedChange.Action == plans.Update && actualChange.Action == plans.NoOp: + // It's okay for an update to become a NoOp once we've filled in + // all of the unknown values, since the final values might actually + // match what was there before after all. + log.Printf("[DEBUG] After incorporating new values learned so far during apply, %s change has become NoOp", absAddr) + default: + diags = diags.Append(tfdiags.Sourceless( + tfdiags.Error, + "Provider produced inconsistent final plan", + fmt.Sprintf( + "When expanding the plan for %s to include new values learned so far during apply, provider %q changed the planned action from %s to %s.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", + absAddr, n.ProviderAddr.ProviderConfig.Type, + plannedChange.Action, actualChange.Action, + ), + )) + } } errs := objchange.AssertObjectCompatible(schema, plannedChange.After, actualChange.After)