Skip to content

Commit

Permalink
Merge pull request #188 from hashicorp/cherry-pick-22895
Browse files Browse the repository at this point in the history
ensure data sources are always written to state (cherry-pick hashicorp/terraform#22895)
  • Loading branch information
kmoe authored Sep 27, 2019
2 parents f66c6b4 + 86477c8 commit d52a6d3
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 16 deletions.
58 changes: 58 additions & 0 deletions terraform/context_refresh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
}
22 changes: 6 additions & 16 deletions terraform/node_data_refresh.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,22 +162,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.
Expand All @@ -191,6 +175,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{
Expand Down
14 changes: 14 additions & 0 deletions terraform/testdata/plan-data-depends-on/main.tf
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit d52a6d3

Please sign in to comment.