ensure data sources are always written to state
The old logic for `depends_on` was to short-circuit evaluation of the data source, but that prevented a plan and state from being recorded. Use the (currently unused) ForcePlanRead to ensure that the plan is recorded when the config contains `depends_on`. This does not fix the fact that depends on does not work with data sources, and will still produce a perpetual diff. This is only to fix evaluation errors when an indexed data source is evaluated during refresh.
This commit is contained in:
parent
e1d0acda0b
commit
aacfaa4fd7
|
@ -1906,3 +1906,61 @@ data "aws_data_source" "foo" {
|
|||
t.Fatal("ValidateDataSourceConfig not called during plan")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Refresh_dataResourceDependsOn(t *testing.T) {
|
||||
m := testModule(t, "plan-data-depends-on")
|
||||
p := testProvider("test")
|
||||
p.GetSchemaReturn = &ProviderSchema{
|
||||
ResourceTypes: map[string]*configschema.Block{
|
||||
"test_resource": {
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"id": {Type: cty.String, Computed: true},
|
||||
"foo": {Type: cty.String, Optional: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
DataSources: map[string]*configschema.Block{
|
||||
"test_data": {
|
||||
Attributes: map[string]*configschema.Attribute{
|
||||
"compute": {Type: cty.String, Computed: true},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
p.DiffFn = testDiffFn
|
||||
|
||||
s := MustShimLegacyState(&State{
|
||||
Modules: []*ModuleState{
|
||||
&ModuleState{
|
||||
Path: rootModulePath,
|
||||
Resources: map[string]*ResourceState{
|
||||
"test_resource.a": &ResourceState{
|
||||
Type: "test_resource",
|
||||
Provider: "provider.test",
|
||||
Primary: &InstanceState{
|
||||
ID: "a",
|
||||
Attributes: map[string]string{
|
||||
"id": "a",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Config: m,
|
||||
ProviderResolver: providers.ResolverFixed(
|
||||
map[string]providers.Factory{
|
||||
"test": testProviderFuncFixed(p),
|
||||
},
|
||||
),
|
||||
State: s,
|
||||
})
|
||||
|
||||
_, diags := ctx.Refresh()
|
||||
if diags.HasErrors() {
|
||||
t.Fatalf("unexpected errors: %s", diags.Err())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,22 +163,6 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode {
|
|||
ProviderSchema: &providerSchema,
|
||||
},
|
||||
|
||||
&EvalIf{
|
||||
If: func(ctx EvalContext) (bool, error) {
|
||||
// If the config explicitly has a depends_on for this
|
||||
// data source, assume the intention is to prevent
|
||||
// refreshing ahead of that dependency, and therefore
|
||||
// we need to deal with this resource during the apply
|
||||
// phase..
|
||||
if len(n.Config.DependsOn) > 0 {
|
||||
return true, EvalEarlyExitError{}
|
||||
}
|
||||
|
||||
return true, nil
|
||||
},
|
||||
Then: EvalNoop{},
|
||||
},
|
||||
|
||||
// EvalReadData will _attempt_ to read the data source, but may
|
||||
// generate an incomplete planned object if the configuration
|
||||
// includes values that won't be known until apply.
|
||||
|
@ -192,6 +176,12 @@ func (n *NodeRefreshableDataResourceInstance) EvalTree() EvalNode {
|
|||
OutputChange: &change,
|
||||
OutputConfigValue: &configVal,
|
||||
OutputState: &state,
|
||||
// If the config explicitly has a depends_on for this data
|
||||
// source, assume the intention is to prevent refreshing ahead
|
||||
// of that dependency, and therefore we need to deal with this
|
||||
// resource during the apply phase. We do that by forcing this
|
||||
// read to result in a plan.
|
||||
ForcePlanRead: len(n.Config.DependsOn) > 0,
|
||||
},
|
||||
|
||||
&EvalIf{
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
resource "test_resource" "a" {
|
||||
}
|
||||
|
||||
data "test_data" "d" {
|
||||
count = 1
|
||||
depends_on = [
|
||||
test_resource.a
|
||||
]
|
||||
}
|
||||
|
||||
resource "test_resource" "b" {
|
||||
count = 1
|
||||
foo = data.test_data.d[count.index].compute
|
||||
}
|
Loading…
Reference in New Issue