From f0ee0ef5cc7eda45b0e0e817375c027512f0a23f Mon Sep 17 00:00:00 2001 From: James Bardin Date: Tue, 11 May 2021 17:55:27 -0400 Subject: [PATCH] decode output ChangeSrc rather than value When an output change was decoded, we were decoding the raw value rather than the ChangeSrc, which lost any encoded marks for that value. --- terraform/context_apply2_test.go | 61 ++++++++++++++++++++++++++++++++ terraform/node_output.go | 6 ++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/terraform/context_apply2_test.go b/terraform/context_apply2_test.go index 28e655bf8..e593c4e76 100644 --- a/terraform/context_apply2_test.go +++ b/terraform/context_apply2_test.go @@ -446,3 +446,64 @@ resource "test_resource" "b" { t.Fatal(diags.ErrWithWarnings()) } } + +func TestContext2Apply_sensitiveOutputPassthrough(t *testing.T) { + // Ensure we're not trying to double-mark values decoded from state + m := testModuleInline(t, map[string]string{ + "main.tf": ` +module "mod" { + source = "./mod" +} + +resource "test_object" "a" { + test_string = module.mod.out +} +`, + + "mod/main.tf": ` +variable "in" { + sensitive = true + default = "foo" +} +output "out" { + value = var.in +} +`, + }) + + p := simpleMockProvider() + + ctx := testContext2(t, &ContextOpts{ + Config: m, + Providers: map[addrs.Provider]providers.Factory{ + addrs.NewDefaultProvider("test"): testProviderFuncFixed(p), + }, + }) + + _, diags := ctx.Plan() + if diags.HasErrors() { + t.Fatal(diags.ErrWithWarnings()) + } + + state, diags := ctx.Apply() + if diags.HasErrors() { + t.Fatal(diags.ErrWithWarnings()) + } + + obj := state.ResourceInstance(mustResourceInstanceAddr("test_object.a")) + if len(obj.Current.AttrSensitivePaths) != 1 { + t.Fatalf("Expected 1 sensitive mark for test_object.a, got %#v\n", obj.Current.AttrSensitivePaths) + } + + plan, diags := ctx.Plan() + if diags.HasErrors() { + t.Fatal(diags.ErrWithWarnings()) + } + + // make sure the same marks are compared in the next plan as well + for _, c := range plan.Changes.Resources { + if c.Action != plans.NoOp { + t.Errorf("Unexpcetd %s change for %s", c.Action, c.Addr) + } + } +} diff --git a/terraform/node_output.go b/terraform/node_output.go index 4db2055c8..2ec5ccbf9 100644 --- a/terraform/node_output.go +++ b/terraform/node_output.go @@ -259,9 +259,11 @@ func (n *NodeApplyableOutput) Execute(ctx EvalContext, op walkOperation) (diags // we we have a change recorded, we don't need to re-evaluate if the value // was known if changeRecorded { - var err error - val, err = n.Change.After.Decode(cty.DynamicPseudoType) + change, err := n.Change.Decode() diags = diags.Append(err) + if err == nil { + val = change.After + } } // If there was no change recorded, or the recorded change was not wholly