diff --git a/terraform/context_plan_test.go b/terraform/context_plan_test.go index e113ae6f5..e9cb4a1d4 100644 --- a/terraform/context_plan_test.go +++ b/terraform/context_plan_test.go @@ -6333,3 +6333,40 @@ func TestContext2Plan_targetedModuleInstance(t *testing.T) { } } } + +func TestContext2Plan_dataRefreshedInPlan(t *testing.T) { + m := testModuleInline(t, map[string]string{ + "main.tf": ` +data "test_data_source" "d" { +} +`}) + + p := testProvider("test") + p.ReadDataSourceResponse = providers.ReadDataSourceResponse{ + State: cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("this"), + "foo": cty.NullVal(cty.String), + }), + } + + ctx := testContext2(t, &ContextOpts{ + Config: m, + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), + }, + }) + + plan, diags := ctx.Plan() + if diags.HasErrors() { + t.Fatal(diags.ErrWithWarnings()) + } + + d := plan.State.ResourceInstance(mustResourceInstanceAddr("data.test_data_source.d")) + if d == nil || d.Current == nil { + t.Fatal("data.test_data_source.d not found in state:", plan.State) + } + + if d.Current.Status != states.ObjectReady { + t.Fatal("expected data.test_data_source.d to be fully read in refreshed state, got status", d.Current.Status) + } +} diff --git a/terraform/eval_read_data_plan.go b/terraform/eval_read_data_plan.go index f13381855..e65ddca2e 100644 --- a/terraform/eval_read_data_plan.go +++ b/terraform/eval_read_data_plan.go @@ -138,6 +138,8 @@ func (n *evalReadDataPlan) Eval(ctx EvalContext) (interface{}, error) { } } + // We still default to read here, to indicate any changes in the plan, even + // though this will already be written in the refreshed state. action := plans.Read if priorVal.Equals(newVal).True() { action = plans.NoOp @@ -159,7 +161,7 @@ func (n *evalReadDataPlan) Eval(ctx EvalContext) (interface{}, error) { *n.State = &states.ResourceInstanceObject{ Value: newVal, - Status: states.ObjectPlanned, + Status: states.ObjectReady, } if err := ctx.Hook(func(h Hook) (HookAction, error) { diff --git a/terraform/node_resource_plan_instance.go b/terraform/node_resource_plan_instance.go index 12bbd5c7d..7cad9d4a4 100644 --- a/terraform/node_resource_plan_instance.go +++ b/terraform/node_resource_plan_instance.go @@ -86,6 +86,16 @@ func (n *NodePlannableResourceInstance) evalTreeDataResource(addr addrs.AbsResou }, }, + // write the data source into both the refresh state and the + // working state + &EvalWriteState{ + Addr: addr.Resource, + ProviderAddr: n.ResolvedProvider, + ProviderSchema: &providerSchema, + State: &state, + targetState: refreshState, + }, + &EvalWriteState{ Addr: addr.Resource, ProviderAddr: n.ResolvedProvider,