Merge pull request #26284 from hashicorp/jbardin/data-resource-reference

delay data source reads with pending resource ref
This commit is contained in:
James Bardin 2020-09-21 16:34:19 -04:00 committed by GitHub
commit abf30de16e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 64 additions and 0 deletions

View File

@ -6370,3 +6370,41 @@ data "test_data_source" "d" {
t.Fatal("expected data.test_data_source.d to be fully read in refreshed state, got status", d.Current.Status)
}
}
func TestContext2Plan_dataReferencesResource(t *testing.T) {
p := testProvider("test")
p.ApplyFn = testApplyFn
p.DiffFn = testDiffFn
p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) (resp providers.ReadDataSourceResponse) {
resp.Diagnostics = resp.Diagnostics.Append(fmt.Errorf("data source should not be read"))
return resp
}
m := testModuleInline(t, map[string]string{
"main.tf": `
locals {
x = "value"
}
resource "test_resource" "a" {
value = local.x
}
// test_resource.a.value can be resolved during plan, but the reference implies
// that the data source should wait until the resource is created.
data "test_data_source" "d" {
foo = test_resource.a.value
}
`})
ctx := testContext2(t, &ContextOpts{
Config: m,
Providers: map[addrs.Provider]providers.Factory{
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
},
})
_, diags := ctx.Plan()
assertNoErrors(t, diags)
}

View File

@ -46,6 +46,7 @@ type GraphNodeAttachDependencies interface {
// graphNodeDependsOn is implemented by resources that need to expose any
// references set via DependsOn in their configuration.
type graphNodeDependsOn interface {
GraphNodeReferencer
DependsOn() []*addrs.Reference
}
@ -327,6 +328,31 @@ func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) ([]dag.Ve
refs := depender.DependsOn()
// For data sources we implicitly treat references as depends_on entries.
// If a data source references a resource, even if that reference is
// resolvable, it stands to reason that the user intends for the data
// source to require that resource in some way.
if n, ok := depender.(GraphNodeConfigResource); ok &&
n.ResourceAddr().Resource.Mode == addrs.DataResourceMode {
for _, r := range depender.References() {
// We don't need to wait on referenced data sources. They have no
// side effects, so our configuration reference should suffice for
// proper ordering.
var resAddr addrs.Resource
switch s := r.Subject.(type) {
case addrs.Resource:
resAddr = s
case addrs.ResourceInstance:
resAddr = s.Resource
}
if resAddr.Mode == addrs.ManagedResourceMode {
refs = append(refs, r)
}
}
}
// This is where we record that a module has depends_on configured.
if _, ok := depender.(*nodeExpandModule); ok && len(refs) > 0 {
fromModule = true