mirror of
https://github.com/opentofu/opentofu.git
synced 2025-01-27 17:06:27 -06:00
data source depends_on
A data source referencing another data source through depends_on should not be forced to defer until apply. Data sources have no side effects, so nothing should need to be applied. If the dependency has a planned change due to a managed resource, the original data source will also encounter that further down the list of dependencies. This prevents a data source being read during plan for any reason from causing other data sources to be deferred until apply. It does not change the behavior noticeably in 0.14, but because 0.13 still had separate refresh and plan phases which could read the data source, the deferral could cause many things downstream to become unexpectedly unknown until apply.
This commit is contained in:
parent
ef64df950c
commit
ea9096fb21
@ -6414,3 +6414,61 @@ resource "test_instance" "a" {
|
||||
t.Fatal("Resource should not have been refreshed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContext2Plan_dataInModuleDependsOn(t *testing.T) {
|
||||
p := testProvider("test")
|
||||
p.ApplyFn = testApplyFn
|
||||
p.DiffFn = testDiffFn
|
||||
|
||||
readDataSourceB := false
|
||||
p.ReadDataSourceFn = func(req providers.ReadDataSourceRequest) (resp providers.ReadDataSourceResponse) {
|
||||
cfg := req.Config.AsValueMap()
|
||||
foo := cfg["foo"].AsString()
|
||||
|
||||
cfg["id"] = cty.StringVal("ID")
|
||||
cfg["foo"] = cty.StringVal("new")
|
||||
|
||||
if foo == "b" {
|
||||
readDataSourceB = true
|
||||
}
|
||||
|
||||
resp.State = cty.ObjectVal(cfg)
|
||||
return resp
|
||||
}
|
||||
|
||||
m := testModuleInline(t, map[string]string{
|
||||
"main.tf": `
|
||||
module "a" {
|
||||
source = "./mod_a"
|
||||
}
|
||||
|
||||
module "b" {
|
||||
source = "./mod_b"
|
||||
depends_on = [module.a]
|
||||
}`,
|
||||
"mod_a/main.tf": `
|
||||
data "test_data_source" "a" {
|
||||
foo = "a"
|
||||
}`,
|
||||
"mod_b/main.tf": `
|
||||
data "test_data_source" "b" {
|
||||
foo = "b"
|
||||
}`,
|
||||
})
|
||||
|
||||
ctx := testContext2(t, &ContextOpts{
|
||||
Config: m,
|
||||
Providers: map[addrs.Provider]providers.Factory{
|
||||
addrs.NewDefaultProvider("test"): testProviderFuncFixed(p),
|
||||
},
|
||||
})
|
||||
|
||||
_, diags := ctx.Plan()
|
||||
assertNoErrors(t, diags)
|
||||
|
||||
// The change to data source a should not prevent data source b from being
|
||||
// read.
|
||||
if !readDataSourceB {
|
||||
t.Fatal("data source b was not read during plan")
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"github.com/hashicorp/terraform/addrs"
|
||||
"github.com/hashicorp/terraform/plans"
|
||||
"github.com/hashicorp/terraform/plans/objchange"
|
||||
"github.com/hashicorp/terraform/states"
|
||||
@ -154,6 +155,14 @@ func (n *evalReadDataPlan) forcePlanRead(ctx EvalContext) bool {
|
||||
// configuration.
|
||||
changes := ctx.Changes()
|
||||
for _, d := range n.dependsOn {
|
||||
if d.Resource.Mode == addrs.DataResourceMode {
|
||||
// Data sources have no external side effects, so they pose a need
|
||||
// to delay this read. If they do have a change planned, it must be
|
||||
// because of a dependency on a managed resource, in which case
|
||||
// we'll also encounter it in this list of dependencies.
|
||||
continue
|
||||
}
|
||||
|
||||
for _, change := range changes.GetChangesForConfigResource(d) {
|
||||
if change != nil && change.Action != plans.NoOp {
|
||||
return true
|
||||
|
Loading…
Reference in New Issue
Block a user