diff --git a/terraform/context.go b/terraform/context.go index cc2e5c7b7..07235776e 100644 --- a/terraform/context.go +++ b/terraform/context.go @@ -503,7 +503,6 @@ Note that the -target option is not suitable for routine use, and is provided on func (c *Context) Plan() (*plans.Plan, tfdiags.Diagnostics) { defer c.acquireRun("plan")() c.changes = plans.NewChanges() - var diags tfdiags.Diagnostics if len(c.targets) > 0 { @@ -575,6 +574,7 @@ The -target option is not for routine use, and is provided only for exceptional diags = diags.Append(walker.NonFatalDiagnostics) diags = diags.Append(walkDiags) if walkDiags.HasErrors() { + fmt.Println("walkerr") return nil, diags } p.Changes = c.changes diff --git a/terraform/context_plan_test.go b/terraform/context_plan_test.go index b81f730af..c981834bc 100644 --- a/terraform/context_plan_test.go +++ b/terraform/context_plan_test.go @@ -5626,6 +5626,61 @@ resource "aws_instance" "foo" { } } +func TestContext2Plan_variableSensitivity(t *testing.T) { + m := testModule(t, "plan-variable-sensitivity") + + p := testProvider("aws") + p.ValidateResourceTypeConfigFn = func(req providers.ValidateResourceTypeConfigRequest) (resp providers.ValidateResourceTypeConfigResponse) { + foo := req.Config.GetAttr("foo").AsString() + if foo == "bar" { + resp.Diagnostics = resp.Diagnostics.Append(errors.New("foo cannot be bar")) + } + return + } + + p.PlanResourceChangeFn = func(req providers.PlanResourceChangeRequest) (resp providers.PlanResourceChangeResponse) { + resp.PlannedState = req.ProposedNewState + return + } + + ctx := testContext2(t, &ContextOpts{ + Config: m, + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("aws"): testProviderFuncFixed(p), + }, + }) + + plan, diags := ctx.Plan() + if diags.HasErrors() { + t.Fatalf("unexpected errors: %s", diags.Err()) + } + schema := p.GetSchemaReturn.ResourceTypes["aws_instance"] + ty := schema.ImpliedType() + + if len(plan.Changes.Resources) != 1 { + t.Fatal("expected 1 changes, got", len(plan.Changes.Resources)) + } + + for _, res := range plan.Changes.Resources { + if res.Action != plans.Create { + t.Fatalf("expected resource creation, got %s", res.Action) + } + ric, err := res.Decode(ty) + if err != nil { + t.Fatal(err) + } + + switch i := ric.Addr.String(); i { + case "aws_instance.foo": + checkVals(t, objectVal(t, schema, map[string]cty.Value{ + "foo": cty.StringVal("foo"), + }), ric.After) + default: + t.Fatal("unknown instance:", i) + } + } +} + func checkVals(t *testing.T, expected, got cty.Value) { t.Helper() if !cmp.Equal(expected, got, valueComparer, typeComparer, equateEmpty) { diff --git a/terraform/eval_diff.go b/terraform/eval_diff.go index ac3f3ca6b..dcd25297e 100644 --- a/terraform/eval_diff.go +++ b/terraform/eval_diff.go @@ -256,6 +256,11 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { panic(fmt.Sprintf("PlanResourceChange of %s produced nil value", absAddr.String())) } + // Add the marks back to the planned new value + if configVal.ContainsMarked() { + plannedNewVal = plannedNewVal.MarkWithPaths(unmarkedPaths) + } + // We allow the planned new value to disagree with configuration _values_ // here, since that allows the provider to do special logic like a // DiffSuppressFunc, but we still require that the provider produces @@ -473,11 +478,6 @@ func (n *EvalDiff) Eval(ctx EvalContext) (interface{}, error) { } } - // Add the marks back to the planned new value - if configVal.ContainsMarked() { - plannedNewVal = plannedNewVal.MarkWithPaths(unmarkedPaths) - } - // Call post-refresh hook if !n.Stub { err := ctx.Hook(func(h Hook) (HookAction, error) { diff --git a/terraform/testdata/plan-variable-sensitivity/main.tf b/terraform/testdata/plan-variable-sensitivity/main.tf new file mode 100644 index 000000000..e8b02a77c --- /dev/null +++ b/terraform/testdata/plan-variable-sensitivity/main.tf @@ -0,0 +1,12 @@ +terraform { + experiments = [sensitive_variables] +} + +variable "sensitive_var" { + default = "foo" + sensitive = true +} + +resource "aws_instance" "foo" { + foo = var.sensitive_var +} \ No newline at end of file