Merge pull request #26284 from hashicorp/jbardin/data-resource-reference
delay data source reads with pending resource ref
This commit is contained in:
commit
abf30de16e
|
@ -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)
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ type GraphNodeAttachDependencies interface {
|
||||||
// graphNodeDependsOn is implemented by resources that need to expose any
|
// graphNodeDependsOn is implemented by resources that need to expose any
|
||||||
// references set via DependsOn in their configuration.
|
// references set via DependsOn in their configuration.
|
||||||
type graphNodeDependsOn interface {
|
type graphNodeDependsOn interface {
|
||||||
|
GraphNodeReferencer
|
||||||
DependsOn() []*addrs.Reference
|
DependsOn() []*addrs.Reference
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,6 +328,31 @@ func (m ReferenceMap) dependsOn(g *Graph, depender graphNodeDependsOn) ([]dag.Ve
|
||||||
|
|
||||||
refs := depender.DependsOn()
|
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.
|
// This is where we record that a module has depends_on configured.
|
||||||
if _, ok := depender.(*nodeExpandModule); ok && len(refs) > 0 {
|
if _, ok := depender.(*nodeExpandModule); ok && len(refs) > 0 {
|
||||||
fromModule = true
|
fromModule = true
|
||||||
|
|
Loading…
Reference in New Issue