detect new outputs and plans as Create actions

Rather than using a prior value of null to indicate create, which is
imprecise because null is a valid output value, only plan values that
didn't exist in the prior state as Create changes.
This commit is contained in:
James Bardin 2021-01-14 09:24:47 -05:00
parent 57f004e0ef
commit 191124e9c9
2 changed files with 34 additions and 2 deletions

View File

@ -6714,3 +6714,29 @@ output "planned" {
}
}
}
func TestContext2Plan_createOutput(t *testing.T) {
// this should always plan a NoOp change for the output
m := testModuleInline(t, map[string]string{
"main.tf": `
output "planned" {
value = 1
}
`,
})
ctx := testContext2(t, &ContextOpts{
Config: m,
State: states.NewState(),
})
plan, diags := ctx.Plan()
if diags.HasErrors() {
t.Fatal(diags.Err())
}
for _, c := range plan.Changes.Outputs {
if c.Action != plans.Create {
t.Fatalf("expected Create change, got %s for %q", c.Action, c.Addr)
}
}
}

View File

@ -432,12 +432,17 @@ func (n *NodeApplyableOutput) setValue(state *states.SyncState, changes *plans.C
// the diff
sensitiveBefore := false
before := cty.NullVal(cty.DynamicPseudoType)
// is this output new to our state?
newOutput := true
mod := state.Module(n.Addr.Module)
if n.Addr.Module.IsRoot() && mod != nil {
for name, o := range mod.OutputValues {
if name == n.Addr.OutputValue.Name {
before = o.Value
sensitiveBefore = o.Sensitive
newOutput = false
break
}
}
@ -455,10 +460,11 @@ func (n *NodeApplyableOutput) setValue(state *states.SyncState, changes *plans.C
switch {
case val.IsNull() && before.IsNull():
// This is separate from the NoOp case below, since we can ignore
// sensitivity here if there are only null values.
// sensitivity here when there are only null values.
action = plans.NoOp
case before.IsNull():
case newOutput:
// This output was just added to the configuration
action = plans.Create
case val.IsWhollyKnown() &&