From 426a976c935fa3bd106a6102be7adfeada3723a5 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Fri, 7 Sep 2018 17:45:51 -0400 Subject: [PATCH] finish context refresh tests --- terraform/context_refresh_test.go | 477 ++++++++++++++++-------------- terraform/eval_output.go | 6 +- terraform/eval_read_data.go | 20 +- terraform/eval_refresh.go | 2 +- terraform/eval_state.go | 4 +- terraform/node_data_refresh.go | 15 +- terraform/node_resource_apply.go | 15 +- terraform/terraform_test.go | 2 - 8 files changed, 295 insertions(+), 246 deletions(-) diff --git a/terraform/context_refresh_test.go b/terraform/context_refresh_test.go index a4598e2c40..17032b604b 100644 --- a/terraform/context_refresh_test.go +++ b/terraform/context_refresh_test.go @@ -712,6 +712,10 @@ func TestContext2Refresh_output(t *testing.T) { ResourceTypes: map[string]*configschema.Block{ "aws_instance": { Attributes: map[string]*configschema.Attribute{ + "id": { + Type: cty.String, + Computed: true, + }, "foo": { Type: cty.String, Computed: true, @@ -739,6 +743,7 @@ func TestContext2Refresh_output(t *testing.T) { Primary: &InstanceState{ ID: "foo", Attributes: map[string]string{ + "id": "foo", "foo": "bar", }, }, @@ -757,12 +762,6 @@ func TestContext2Refresh_output(t *testing.T) { }), }) - p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse { - return providers.ReadResourceResponse{ - NewState: req.PriorState, - } - } - s, diags := ctx.Refresh() if diags.HasErrors() { t.Fatalf("refresh errors: %s", diags.Err()) @@ -771,7 +770,7 @@ func TestContext2Refresh_output(t *testing.T) { actual := strings.TrimSpace(s.String()) expected := strings.TrimSpace(testContextRefreshOutputStr) if actual != expected { - t.Fatalf("wrong result\n\ngot:\n%s\n\nwant:\n%s", actual, expected) + t.Fatalf("wrong result\n\ngot:\n%q\n\nwant:\n%q", actual, expected) } } @@ -804,7 +803,9 @@ func TestContext2Refresh_outputPartial(t *testing.T) { }) p.ReadResourceFn = nil - p.ReadResourceResponse = providers.ReadResourceResponse{} + p.ReadResourceResponse = providers.ReadResourceResponse{ + NewState: cty.NullVal(p.GetSchemaReturn.ResourceTypes["aws_instance"].ImpliedType()), + } // Refresh creates a partial plan for any instances that don't have // remote objects yet, to get stub values for interpolation. Therefore @@ -838,59 +839,66 @@ func TestContext2Refresh_outputPartial(t *testing.T) { } func TestContext2Refresh_stateBasic(t *testing.T) { - t.Fatalf("not yet updated for new provider interface") - /* - p := testProvider("aws") - m := testModule(t, "refresh-basic") - state := mustShimLegacyState(&State{ - Modules: []*ModuleState{ - &ModuleState{ - Path: rootModulePath, - Resources: map[string]*ResourceState{ - "aws_instance.web": &ResourceState{ - Type: "aws_instance", - Primary: &InstanceState{ - ID: "bar", - }, + p := testProvider("aws") + m := testModule(t, "refresh-basic") + state := mustShimLegacyState(&State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: rootModulePath, + Resources: map[string]*ResourceState{ + "aws_instance.web": &ResourceState{ + Type: "aws_instance", + Primary: &InstanceState{ + ID: "bar", }, }, }, }, - }) - ctx := testContext2(t, &ContextOpts{ - Config: m, - ProviderResolver: providers.ResolverFixed( - map[string]providers.Factory{ - "aws": testProviderFuncFixed(p), - }, - ), - State: state, - }) + }, + }) + ctx := testContext2(t, &ContextOpts{ + Config: m, + ProviderResolver: providers.ResolverFixed( + map[string]providers.Factory{ + "aws": testProviderFuncFixed(p), + }, + ), + State: state, + }) - p.RefreshFn = nil - p.RefreshReturn = &InstanceState{ - ID: "foo", - } + schema := p.GetSchemaReturn.ResourceTypes["aws_instance"] + ty := schema.ImpliedType() - s, diags := ctx.Refresh() - if diags.HasErrors() { - t.Fatalf("refresh errors: %s", diags.Err()) - } - originalMod := state.RootModule() - mod := s.RootModule() - if !p.RefreshCalled { - t.Fatal("refresh should be called") - } - if !reflect.DeepEqual(p.RefreshState, originalMod.Resources["aws_instance.web"].Primary) { - t.Fatalf( - "bad:\n\n%#v\n\n%#v", - p.RefreshState, - originalMod.Resources["aws_instance.web"].Primary) - } - if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) { - t.Fatalf("bad: %#v", mod.Resources) - } - */ + readStateVal, err := schema.CoerceValue(cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("foo"), + })) + if err != nil { + t.Fatal(err) + } + + p.ReadResourceFn = nil + p.ReadResourceResponse = providers.ReadResourceResponse{ + NewState: readStateVal, + } + + s, diags := ctx.Refresh() + if diags.HasErrors() { + t.Fatalf("refresh errors: %s", diags.Err()) + } + + if !p.ReadResourceCalled { + t.Fatal("read resource should be called") + } + + mod := s.RootModule() + newState, err := mod.Resources["aws_instance.web"].Instances[addrs.NoKey].Current.Decode(ty) + if err != nil { + t.Fatal(err) + } + + if !cmp.Equal(readStateVal, newState.Value, valueComparer, equateEmpty) { + t.Fatal(cmp.Diff(readStateVal, newState.Value, valueComparer, equateEmpty)) + } } func TestContext2Refresh_dataOrphan(t *testing.T) { @@ -929,94 +937,106 @@ func TestContext2Refresh_dataOrphan(t *testing.T) { } func TestContext2Refresh_dataState(t *testing.T) { - t.Fatalf("not yet updated for new provider interface") - /* - m := testModule(t, "refresh-data-resource-basic") + m := testModule(t, "refresh-data-resource-basic") - state := mustShimLegacyState(&State{ - Modules: []*ModuleState{ - &ModuleState{ - Path: rootModulePath, - // Intentionally no resources since data resources are - // supposed to refresh themselves even if they didn't - // already exist. - Resources: map[string]*ResourceState{}, - }, + state := mustShimLegacyState(&State{ + Modules: []*ModuleState{ + &ModuleState{ + Path: rootModulePath, + // Intentionally no resources since data resources are + // supposed to refresh themselves even if they didn't + // already exist. + Resources: map[string]*ResourceState{}, }, - }) + }, + }) - p := testProvider("null") - p.GetSchemaReturn = &ProviderSchema{ - Provider: &configschema.Block{}, - DataSources: map[string]*configschema.Block{ - "null_data_source": { - Attributes: map[string]*configschema.Attribute{ - "inputs": { - Type: cty.Map(cty.String), - Optional: true, - }, - }, - }, + schema := &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "inputs": { + Type: cty.Map(cty.String), + Optional: true, }, - } + }, + } - ctx := testContext2(t, &ContextOpts{ - Config: m, - ProviderResolver: providers.ResolverFixed( - map[string]providers.Factory{ - "null": testProviderFuncFixed(p), - }, - ), - State: state, - }) + p := testProvider("null") + p.GetSchemaReturn = &ProviderSchema{ + Provider: &configschema.Block{}, + DataSources: map[string]*configschema.Block{ + "null_data_source": schema, + }, + } - p.ReadDataDiffFn = nil - p.ReadDataDiffReturn = &InstanceDiff{ - Attributes: map[string]*ResourceAttrDiff{ - "inputs.#": { - Old: "0", - New: "1", - Type: DiffAttrInput, - }, - "inputs.test": { - Old: "", - New: "yes", - Type: DiffAttrInput, - }, - "outputs.#": { - Old: "", - New: "", - NewComputed: true, - Type: DiffAttrOutput, - }, + ctx := testContext2(t, &ContextOpts{ + Config: m, + ProviderResolver: providers.ResolverFixed( + map[string]providers.Factory{ + "null": testProviderFuncFixed(p), }, + ), + State: state, + }) + + var readStateVal cty.Value + + p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) providers.ReadDataSourceResponse { + m := req.Config.AsValueMap() + m["inputs"] = cty.MapVal(map[string]cty.Value{"test": cty.StringVal("yes")}) + readStateVal = cty.ObjectVal(m) + + return providers.ReadDataSourceResponse{ + State: readStateVal, } - p.ReadDataApplyFn = nil - p.ReadDataApplyReturn = &InstanceState{ - ID: "-", - } + // FIXME: should the "outputs" value here be added to the reutnred state? + // Attributes: map[string]*ResourceAttrDiff{ + // "inputs.#": { + // Old: "0", + // New: "1", + // Type: DiffAttrInput, + // }, + // "inputs.test": { + // Old: "", + // New: "yes", + // Type: DiffAttrInput, + // }, + // "outputs.#": { + // Old: "", + // New: "", + // NewComputed: true, + // Type: DiffAttrOutput, + // }, + // }, + } - s, diags := ctx.Refresh() - if diags.HasErrors() { - t.Fatalf("refresh errors: %s", diags.Err()) - } + s, diags := ctx.Refresh() + if diags.HasErrors() { + t.Fatalf("refresh errors: %s", diags.Err()) + } - if !p.ReadDataDiffCalled { - t.Fatal("ReadDataDiff should have been called") - } - if !p.ReadDataApplyCalled { - t.Fatal("ReadDataApply should have been called") - } + if !p.ReadDataSourceCalled { + t.Fatal("ReadDataSource should have been called") + } - mod := s.RootModule() - if got := mod.Resources["data.null_data_source.testing"].Primary.ID; got != "-" { - t.Fatalf("resource id is %q; want %s", got, "-") - } - if !reflect.DeepEqual(mod.Resources["data.null_data_source.testing"].Primary, p.ReadDataApplyReturn) { - t.Fatalf("bad: %#v", mod.Resources) - } - */ + // mod := s.RootModule() + // if got := mod.Resources["data.null_data_source.testing"].Primary.ID; got != "-" { + // t.Fatalf("resource id is %q; want %s", got, "-") + // } + // if !reflect.DeepEqual(mod.Resources["data.null_data_source.testing"].Primary, p.ReadDataApplyReturn) { + // t.Fatalf("bad: %#v", mod.Resources) + // } + + mod := s.RootModule() + + newState, err := mod.Resources["data.null_data_source.testing"].Instances[addrs.NoKey].Current.Decode(schema.ImpliedType()) + if err != nil { + t.Fatal(err) + } + + if !cmp.Equal(readStateVal, newState.Value, valueComparer, equateEmpty) { + t.Fatal(cmp.Diff(readStateVal, newState.Value, valueComparer, equateEmpty)) + } } func TestContext2Refresh_dataStateRefData(t *testing.T) { @@ -1026,6 +1046,10 @@ func TestContext2Refresh_dataStateRefData(t *testing.T) { DataSources: map[string]*configschema.Block{ "null_data_source": { Attributes: map[string]*configschema.Attribute{ + "id": { + Type: cty.String, + Computed: true, + }, "foo": { Type: cty.String, Optional: true, @@ -1062,8 +1086,12 @@ func TestContext2Refresh_dataStateRefData(t *testing.T) { }) p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) providers.ReadDataSourceResponse { + // add the required id + m := req.Config.AsValueMap() + m["id"] = cty.StringVal("foo") + return providers.ReadDataSourceResponse{ - State: req.Config, + State: cty.ObjectVal(m), } } @@ -1107,12 +1135,14 @@ func TestContext2Refresh_tainted(t *testing.T) { ), State: state, }) + p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse { + // add the required id + m := req.PriorState.AsValueMap() + m["id"] = cty.StringVal("foo") - p.ReadResourceFn = nil - p.ReadResourceResponse = providers.ReadResourceResponse{ - NewState: cty.ObjectVal(map[string]cty.Value{ - "id": cty.StringVal("foo"), - }), + return providers.ReadResourceResponse{ + NewState: cty.ObjectVal(m), + } } s, diags := ctx.Refresh() @@ -1172,79 +1202,95 @@ func TestContext2Refresh_unknownProvider(t *testing.T) { } func TestContext2Refresh_vars(t *testing.T) { - t.Fatalf("not yet updated for new provider interface") - /* - p := testProvider("aws") - p.GetSchemaReturn = &ProviderSchema{ - Provider: &configschema.Block{}, - ResourceTypes: map[string]*configschema.Block{ - "aws_instance": { - Attributes: map[string]*configschema.Attribute{ - "ami": { - Type: cty.String, - Optional: true, - }, - "id": { - Type: cty.String, - Computed: true, - }, - }, - }, + p := testProvider("aws") + + schema := &configschema.Block{ + Attributes: map[string]*configschema.Attribute{ + "ami": { + Type: cty.String, + Optional: true, }, - } + "id": { + Type: cty.String, + Computed: true, + }, + }, + } - m := testModule(t, "refresh-vars") - ctx := testContext2(t, &ContextOpts{ - Config: m, - ProviderResolver: providers.ResolverFixed( - map[string]providers.Factory{ - "aws": testProviderFuncFixed(p), - }, - ), - State: mustShimLegacyState(&State{ + p.GetSchemaReturn = &ProviderSchema{ + Provider: &configschema.Block{}, + ResourceTypes: map[string]*configschema.Block{"aws_instance": schema}, + } - Modules: []*ModuleState{ - &ModuleState{ - Path: rootModulePath, - Resources: map[string]*ResourceState{ - "aws_instance.web": &ResourceState{ - Type: "aws_instance", - Primary: &InstanceState{ - ID: "foo", - }, + m := testModule(t, "refresh-vars") + ctx := testContext2(t, &ContextOpts{ + Config: m, + ProviderResolver: providers.ResolverFixed( + map[string]providers.Factory{ + "aws": testProviderFuncFixed(p), + }, + ), + State: mustShimLegacyState(&State{ + + Modules: []*ModuleState{ + &ModuleState{ + Path: rootModulePath, + Resources: map[string]*ResourceState{ + "aws_instance.web": &ResourceState{ + Type: "aws_instance", + Primary: &InstanceState{ + ID: "foo", }, }, }, }, - }), - }) + }, + }), + }) - p.RefreshFn = nil - p.RefreshReturn = &InstanceState{ - ID: "foo", - } + readStateVal, err := schema.CoerceValue(cty.ObjectVal(map[string]cty.Value{ + "id": cty.StringVal("foo"), + })) + if err != nil { + t.Fatal(err) + } - s, diags := ctx.Refresh() - if diags.HasErrors() { - t.Fatalf("refresh errors: %s", diags.Err()) - } - mod := s.RootModule() - if !p.RefreshCalled { - t.Fatal("refresh should be called") - } - if p.RefreshState.ID != "foo" { - t.Fatalf("bad: %#v", p.RefreshState) - } - if !reflect.DeepEqual(mod.Resources["aws_instance.web"].Primary, p.RefreshReturn) { - t.Fatalf("bad: %#v", mod.Resources["aws_instance.web"]) - } + p.ReadResourceFn = nil + p.ReadResourceResponse = providers.ReadResourceResponse{ + NewState: readStateVal, + } - for _, r := range mod.Resources { - if r.Addr.Type == "" { - t.Fatalf("no type: %#v", r) - } + p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) providers.PlanResourceChangeResponse { + return providers.PlanResourceChangeResponse{ + PlannedState: req.ProposedNewState, } - */ + } + + s, diags := ctx.Refresh() + if diags.HasErrors() { + t.Fatalf("refresh errors: %s", diags.Err()) + } + + if !p.ReadResourceCalled { + t.Fatal("read resource should be called") + } + + mod := s.RootModule() + + newState, err := mod.Resources["aws_instance.web"].Instances[addrs.NoKey].Current.Decode(schema.ImpliedType()) + if err != nil { + t.Fatal(err) + } + + if !cmp.Equal(readStateVal, newState.Value, valueComparer, equateEmpty) { + t.Fatal(cmp.Diff(readStateVal, newState.Value, valueComparer, equateEmpty)) + } + + for _, r := range mod.Resources { + if r.Addr.Type == "" { + t.Fatalf("no type: %#v", r) + } + } } func TestContext2Refresh_orphanModule(t *testing.T) { @@ -1263,12 +1309,6 @@ func TestContext2Refresh_orphanModule(t *testing.T) { NewState: req.PriorState, } } - p.GetSchemaReturn = &ProviderSchema{ - Provider: &configschema.Block{}, - ResourceTypes: map[string]*configschema.Block{ - "aws_instance": {}, - }, - } state := mustShimLegacyState(&State{ Modules: []*ModuleState{ @@ -1280,6 +1320,7 @@ func TestContext2Refresh_orphanModule(t *testing.T) { Primary: &InstanceState{ ID: "i-abc123", Attributes: map[string]string{ + "id": "i-abc123", "childid": "i-bcd234", "grandchildid": "i-cde345", }, @@ -1300,6 +1341,7 @@ func TestContext2Refresh_orphanModule(t *testing.T) { Primary: &InstanceState{ ID: "i-bcd234", Attributes: map[string]string{ + "id": "i-bcd234", "grandchildid": "i-cde345", }, }, @@ -1327,6 +1369,9 @@ func TestContext2Refresh_orphanModule(t *testing.T) { Type: "aws_instance", Primary: &InstanceState{ ID: "i-cde345", + Attributes: map[string]string{ + "id": "i-cde345", + }, }, Provider: "provider.aws", }, @@ -1409,13 +1454,6 @@ func TestContext2Refresh_noDiffHookOnScaleOut(t *testing.T) { h := new(MockHook) p := testProvider("aws") m := testModule(t, "refresh-resource-scale-inout") - p.ReadResourceFn = nil - p.GetSchemaReturn = &ProviderSchema{ - Provider: &configschema.Block{}, - ResourceTypes: map[string]*configschema.Block{ - "aws_instance": {}, - }, - } // Refresh creates a partial plan for any instances that don't have // remote objects yet, to get stub values for interpolation. Therefore @@ -1432,6 +1470,9 @@ func TestContext2Refresh_noDiffHookOnScaleOut(t *testing.T) { Deposed: []*InstanceState{ &InstanceState{ ID: "foo", + Attributes: map[string]string{ + "id": "foo", + }, }, }, }, @@ -1440,6 +1481,9 @@ func TestContext2Refresh_noDiffHookOnScaleOut(t *testing.T) { Deposed: []*InstanceState{ &InstanceState{ ID: "bar", + Attributes: map[string]string{ + "id": "foo", + }, }, }, }, @@ -1476,12 +1520,6 @@ func TestContext2Refresh_updateProviderInState(t *testing.T) { p := testProvider("aws") p.DiffFn = testDiffFn p.ApplyFn = testApplyFn - p.GetSchemaReturn = &ProviderSchema{ - Provider: &configschema.Block{}, - ResourceTypes: map[string]*configschema.Block{ - "aws_instance": {}, - }, - } s := mustShimLegacyState(&State{ Modules: []*ModuleState{ @@ -1492,6 +1530,9 @@ func TestContext2Refresh_updateProviderInState(t *testing.T) { Type: "aws_instance", Primary: &InstanceState{ ID: "foo", + Attributes: map[string]string{ + "id": "foo", + }, }, Provider: "provider.aws.baz", }, diff --git a/terraform/eval_output.go b/terraform/eval_output.go index 8bd6261435..5feb95b9ef 100644 --- a/terraform/eval_output.go +++ b/terraform/eval_output.go @@ -63,6 +63,10 @@ func (n *EvalWriteOutput) Eval(ctx EvalContext) (interface{}, error) { return nil, diags.Err() } - state.SetOutputValue(addr, val, n.Sensitive) + if val.IsKnown() && !val.IsNull() { + state.SetOutputValue(addr, val, n.Sensitive) + } else { + state.RemoveOutputValue(addr) + } return nil, nil } diff --git a/terraform/eval_read_data.go b/terraform/eval_read_data.go index a93bfc3373..5510d5ff98 100644 --- a/terraform/eval_read_data.go +++ b/terraform/eval_read_data.go @@ -136,13 +136,14 @@ func (n *EvalReadDataDiff) Eval(ctx EvalContext) (interface{}, error) { // EvalReadDataApply is an EvalNode implementation that executes a data // resource's ReadDataApply method to read data from the data source. type EvalReadDataApply struct { - Addr addrs.ResourceInstance - Provider *providers.Interface - ProviderAddr addrs.AbsProviderConfig - ProviderSchema **ProviderSchema - Output **states.ResourceInstanceObject - Config *configs.Resource - Change **plans.ResourceInstanceChange + Addr addrs.ResourceInstance + Provider *providers.Interface + ProviderAddr addrs.AbsProviderConfig + ProviderSchema **ProviderSchema + Output **states.ResourceInstanceObject + Config *configs.Resource + Change **plans.ResourceInstanceChange + StateReferences []addrs.Referenceable } func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) { @@ -214,8 +215,9 @@ func (n *EvalReadDataApply) Eval(ctx EvalContext) (interface{}, error) { if n.Output != nil { *n.Output = &states.ResourceInstanceObject{ - Value: newVal, - Status: states.ObjectReady, + Value: newVal, + Status: states.ObjectReady, + Dependencies: n.StateReferences, } } diff --git a/terraform/eval_refresh.go b/terraform/eval_refresh.go index a13ef5de78..cb55c5fa99 100644 --- a/terraform/eval_refresh.go +++ b/terraform/eval_refresh.go @@ -76,7 +76,7 @@ func (n *EvalRefresh) Eval(ctx EvalContext) (interface{}, error) { tfdiags.Error, "Provider produced invalid object", fmt.Sprintf( - "Provider %q planned an invalid value for %s%s during refresh.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", + "Provider %q planned an invalid value for %s: %s during refresh.\n\nThis is a bug in the provider, which should be reported in the provider's own issue tracker.", n.ProviderAddr.ProviderConfig.Type, absAddr, tfdiags.FormatError(err), ), )) diff --git a/terraform/eval_state.go b/terraform/eval_state.go index 95cc99a0d9..cec627e598 100644 --- a/terraform/eval_state.go +++ b/terraform/eval_state.go @@ -55,10 +55,12 @@ func (n *EvalReadState) Eval(ctx EvalContext) (interface{}, error) { */ schema := (*n.ProviderSchema).SchemaForResourceAddr(n.Addr.ContainingResource()) + obj, err := src.Decode(schema.ImpliedType()) if err != nil { return nil, err } + if n.Output != nil { *n.Output = obj } @@ -193,7 +195,7 @@ func (n *EvalWriteState) Eval(ctx EvalContext) (interface{}, error) { state := ctx.State() obj := *n.State - if obj == nil { + if obj == nil || obj.Value.IsNull() { // No need to encode anything: we'll just write it directly. state.SetResourceInstanceCurrent(absAddr, nil, n.ProviderAddr) log.Printf("[TRACE] EvalWriteState: removing state object for %s", absAddr) diff --git a/terraform/node_data_refresh.go b/terraform/node_data_refresh.go index 7e4daa1dd5..19e30c6cd5 100644 --- a/terraform/node_data_refresh.go +++ b/terraform/node_data_refresh.go @@ -177,13 +177,14 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode { }, &EvalReadDataApply{ - Addr: addr.Resource, - Config: n.Config, - Change: &change, - Provider: &provider, - ProviderAddr: n.ResolvedProvider, - ProviderSchema: &providerSchema, - Output: &state, + Addr: addr.Resource, + Config: n.Config, + Change: &change, + Provider: &provider, + ProviderAddr: n.ResolvedProvider, + ProviderSchema: &providerSchema, + Output: &state, + StateReferences: n.StateReferences(), }, &EvalWriteState{ diff --git a/terraform/node_resource_apply.go b/terraform/node_resource_apply.go index e2f2dc2d83..795b7caf98 100644 --- a/terraform/node_resource_apply.go +++ b/terraform/node_resource_apply.go @@ -158,13 +158,14 @@ func (n *NodeApplyableResourceInstance) evalTreeDataResource(addr addrs.AbsResou }, &EvalReadDataApply{ - Addr: addr.Resource, - Config: n.Config, - Change: &change, - Provider: &provider, - ProviderAddr: n.ResolvedProvider, - ProviderSchema: &providerSchema, - Output: &state, + Addr: addr.Resource, + Config: n.Config, + Change: &change, + Provider: &provider, + ProviderAddr: n.ResolvedProvider, + ProviderSchema: &providerSchema, + Output: &state, + StateReferences: n.StateReferences(), }, &EvalWriteState{ diff --git a/terraform/terraform_test.go b/terraform/terraform_test.go index b16fdea649..dd42c22f64 100644 --- a/terraform/terraform_test.go +++ b/terraform/terraform_test.go @@ -1800,7 +1800,6 @@ data.null_data_source.bar: ID = foo provider = provider.null bar = yes - type = null_data_source Dependencies: data.null_data_source.foo @@ -1808,5 +1807,4 @@ data.null_data_source.foo: ID = foo provider = provider.null foo = yes - type = null_data_source `