diff --git a/internal/terraform/context_apply_deferred_test.go b/internal/terraform/context_apply_deferred_test.go index dcdb1e289ca7..554d47253dd2 100644 --- a/internal/terraform/context_apply_deferred_test.go +++ b/internal/terraform/context_apply_deferred_test.go @@ -123,6 +123,7 @@ output "c" { "a": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("a"), "upstream_names": cty.NullVal(cty.Set(cty.String)), + "defer_read": cty.NullVal(cty.Bool), }), "": cty.ObjectVal(map[string]cty.Value{ "name": cty.UnknownVal(cty.String).Refine(). @@ -132,10 +133,12 @@ output "c" { "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), "c": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("c"), "upstream_names": cty.UnknownVal(cty.Set(cty.String)).RefineNotNull(), + "defer_read": cty.NullVal(cty.Bool), }), }, wantActions: map[string]plans.Action{ @@ -147,12 +150,14 @@ output "c" { "a": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("a"), "upstream_names": cty.NullVal(cty.Set(cty.String)), + "defer_read": cty.NullVal(cty.Bool), }), }, wantOutputs: map[string]cty.Value{ "a": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("a"), "upstream_names": cty.NullVal(cty.Set(cty.String)), + "defer_read": cty.NullVal(cty.Bool), }), // FIXME: The system is currently producing incorrect @@ -207,6 +212,7 @@ output "c" { "a": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("a"), "upstream_names": cty.NullVal(cty.Set(cty.String)), + "defer_read": cty.NullVal(cty.Bool), }), // test.b is now planned for real, once for each instance "b:1": cty.ObjectVal(map[string]cty.Value{ @@ -214,12 +220,14 @@ output "c" { "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), "b:2": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("b:2"), "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), // test.c gets re-planned, so we can finalize its values // based on the new results from test.b. @@ -230,6 +238,7 @@ output "c" { cty.StringVal("b:1"), cty.StringVal("b:2"), }), + "defer_read": cty.NullVal(cty.Bool), }), }, wantActions: map[string]plans.Action{ @@ -249,12 +258,14 @@ output "c" { "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), "b:2": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("b:2"), "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), "c": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("c"), @@ -263,6 +274,7 @@ output "c" { cty.StringVal("b:1"), cty.StringVal("b:2"), }), + "defer_read": cty.NullVal(cty.Bool), }), }, wantOutputs: map[string]cty.Value{ @@ -271,6 +283,7 @@ output "c" { "a": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("a"), "upstream_names": cty.NullVal(cty.Set(cty.String)), + "defer_read": cty.NullVal(cty.Bool), }), "b": cty.ObjectVal(map[string]cty.Value{ "1": cty.ObjectVal(map[string]cty.Value{ @@ -278,12 +291,14 @@ output "c" { "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), "2": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("b:2"), "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), }), "c": cty.ObjectVal(map[string]cty.Value{ @@ -293,6 +308,7 @@ output "c" { cty.StringVal("b:1"), cty.StringVal("b:2"), }), + "defer_read": cty.NullVal(cty.Bool), }), }, complete: true, @@ -309,18 +325,21 @@ output "c" { "a": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("a"), "upstream_names": cty.NullVal(cty.Set(cty.String)), + "defer_read": cty.NullVal(cty.Bool), }), "b:1": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("b:1"), "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), "b:2": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("b:2"), "upstream_names": cty.SetVal([]cty.Value{ cty.StringVal("a"), }), + "defer_read": cty.NullVal(cty.Bool), }), "c": cty.ObjectVal(map[string]cty.Value{ "name": cty.StringVal("c"), @@ -329,6 +348,7 @@ output "c" { cty.StringVal("b:1"), cty.StringVal("b:2"), }), + "defer_read": cty.NullVal(cty.Bool), }), }, wantActions: map[string]plans.Action{ @@ -356,8 +376,13 @@ terraform { experiments = [unknown_instances] } +variable "defer_read" { + type = bool +} + resource "test" "a" { - name = "deferred_read" + name = "a" + defer_read = var.defer_read } output "a" { @@ -370,7 +395,9 @@ output "a" { buildOpts: func(opts *PlanOpts) { opts.Mode = plans.RefreshOnlyMode }, - inputs: map[string]cty.Value{}, + inputs: map[string]cty.Value{ + "defer_read": cty.True, + }, wantPlanned: map[string]cty.Value{ // The all resources will be deferred, so shouldn't // have any action at this stage. @@ -387,8 +414,52 @@ output "a" { "upstream_names": cty.NullVal(cty.Set(cty.String)), }), }, + complete: false, + }, + { + inputs: map[string]cty.Value{ + "defer_read": cty.False, + }, + wantPlanned: map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("a"), + "defer_read": cty.False, + "upstream_names": cty.NullVal(cty.Set(cty.String)), + }), + }, + + wantActions: map[string]plans.Action{ + `test.a`: plans.Create, + }, + wantApplied: map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("a"), + "defer_read": cty.False, + "upstream_names": cty.NullVal(cty.Set(cty.String)), + }), + }, + wantOutputs: map[string]cty.Value{ + "a": cty.ObjectVal(map[string]cty.Value{ + "name": cty.StringVal("a"), + "upstream_names": cty.NullVal(cty.Set(cty.String)), + "defer_read": cty.False, + }), + }, complete: true, }, + { + inputs: map[string]cty.Value{ + "defer_read": cty.True, + }, + wantPlanned: map[string]cty.Value{ + "a": cty.UnknownAsNull(cty.DynamicVal), + }, + + wantActions: map[string]plans.Action{}, + wantApplied: map[string]cty.Value{}, + wantOutputs: map[string]cty.Value{}, + complete: false, + }, }, } ) @@ -556,13 +627,17 @@ func (provider *deferredActionsProvider) Provider() providers.Interface { Type: cty.Set(cty.String), Optional: true, }, + "defer_read": { + Type: cty.Bool, + Optional: true, + }, }, }, }, }, }, ReadResourceFn: func(req providers.ReadResourceRequest) providers.ReadResourceResponse { - if key := req.PriorState.GetAttr("name"); key.IsKnown() && key.AsString() == "deferred_read" { + if key := req.PriorState.GetAttr("defer_read"); key.IsKnown() && key.True() { return providers.ReadResourceResponse{ NewState: req.PriorState, Deferred: &providers.Deferred{