diff --git a/internal/terraform/context_plan2_test.go b/internal/terraform/context_plan2_test.go index 634144dee0..65f743a39c 100644 --- a/internal/terraform/context_plan2_test.go +++ b/internal/terraform/context_plan2_test.go @@ -1705,6 +1705,60 @@ The -target option is not for routine use, and is provided only for exceptional }) } +func TestContext2Plan_untargetedResourceSchemaChange(t *testing.T) { + // an untargeted resource which requires a schema migration should not + // block planning due external changes in the plan. + addrA := mustResourceInstanceAddr("test_object.a") + addrB := mustResourceInstanceAddr("test_object.b") + m := testModuleInline(t, map[string]string{ + "main.tf": ` +resource "test_object" "a" { +} +resource "test_object" "b" { +}`, + }) + + state := states.BuildState(func(s *states.SyncState) { + s.SetResourceInstanceCurrent(addrA, &states.ResourceInstanceObjectSrc{ + AttrsJSON: []byte(`{}`), + Status: states.ObjectReady, + }, mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`)) + s.SetResourceInstanceCurrent(addrB, &states.ResourceInstanceObjectSrc{ + // old_list is no longer in the schema + AttrsJSON: []byte(`{"old_list":["used to be","a list here"]}`), + Status: states.ObjectReady, + }, mustProviderConfig(`provider["registry.terraform.io/hashicorp/test"]`)) + }) + + p := simpleMockProvider() + + // external changes trigger a "drift report", but because test_object.b was + // not targeted, the state was not fixed to match the schema and cannot be + // deocded for the report. + p.ReadResourceFn = func(req providers.ReadResourceRequest) (resp providers.ReadResourceResponse) { + obj := req.PriorState.AsValueMap() + // test_number changed externally + obj["test_number"] = cty.NumberIntVal(1) + resp.NewState = cty.ObjectVal(obj) + return resp + } + + ctx := testContext2(t, &ContextOpts{ + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), + }, + }) + + _, diags := ctx.Plan(m, state, &PlanOpts{ + Mode: plans.NormalMode, + Targets: []addrs.Targetable{ + addrA, + }, + }) + // + assertNoErrors(t, diags) +} + func TestContext2Plan_movedResourceRefreshOnly(t *testing.T) { addrA := mustResourceInstanceAddr("test_object.a") addrB := mustResourceInstanceAddr("test_object.b")