Merge pull request #26944 from hashicorp/jbardin/module-output-plan
Don't render a plan for module outputs
This commit is contained in:
commit
b06db967b7
|
@ -241,6 +241,56 @@ Changes to Outputs:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Module outputs should not cause the plan to be rendered
|
||||||
|
func TestLocal_planModuleOutputsChanged(t *testing.T) {
|
||||||
|
b, cleanup := TestLocal(t)
|
||||||
|
defer cleanup()
|
||||||
|
testStateFile(t, b.StatePath, states.BuildState(func(ss *states.SyncState) {
|
||||||
|
ss.SetOutputValue(addrs.AbsOutputValue{
|
||||||
|
Module: addrs.RootModuleInstance.Child("mod", addrs.NoKey),
|
||||||
|
OutputValue: addrs.OutputValue{Name: "changed"},
|
||||||
|
}, cty.StringVal("before"), false)
|
||||||
|
}))
|
||||||
|
b.CLI = cli.NewMockUi()
|
||||||
|
outDir := testTempDir(t)
|
||||||
|
defer os.RemoveAll(outDir)
|
||||||
|
planPath := filepath.Join(outDir, "plan.tfplan")
|
||||||
|
op, configCleanup := testOperationPlan(t, "./testdata/plan-module-outputs-changed")
|
||||||
|
defer configCleanup()
|
||||||
|
op.PlanRefresh = true
|
||||||
|
op.PlanOutPath = planPath
|
||||||
|
cfg := cty.ObjectVal(map[string]cty.Value{
|
||||||
|
"path": cty.StringVal(b.StatePath),
|
||||||
|
})
|
||||||
|
cfgRaw, err := plans.NewDynamicValue(cfg, cfg.Type())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
op.PlanOutBackend = &plans.Backend{
|
||||||
|
Type: "local",
|
||||||
|
Config: cfgRaw,
|
||||||
|
}
|
||||||
|
run, err := b.Operation(context.Background(), op)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("bad: %s", err)
|
||||||
|
}
|
||||||
|
<-run.Done()
|
||||||
|
if run.Result != backend.OperationSuccess {
|
||||||
|
t.Fatalf("plan operation failed")
|
||||||
|
}
|
||||||
|
if !run.PlanEmpty {
|
||||||
|
t.Fatal("plan should be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedOutput := strings.TrimSpace(`
|
||||||
|
No changes. Infrastructure is up-to-date.
|
||||||
|
`)
|
||||||
|
output := b.CLI.(*cli.MockUi).OutputWriter.String()
|
||||||
|
if !strings.Contains(output, expectedOutput) {
|
||||||
|
t.Fatalf("Unexpected output:\n%s\n\nwant output containing:\n%s", output, expectedOutput)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestLocal_planTainted(t *testing.T) {
|
func TestLocal_planTainted(t *testing.T) {
|
||||||
b, cleanup := TestLocal(t)
|
b, cleanup := TestLocal(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module "mod" {
|
||||||
|
source = "./mod"
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
output "changed" {
|
||||||
|
value = "after"
|
||||||
|
}
|
|
@ -39,7 +39,7 @@ func (c *Changes) Empty() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, out := range c.Outputs {
|
for _, out := range c.Outputs {
|
||||||
if out.Action != NoOp {
|
if out.Addr.Module.IsRoot() && out.Action != NoOp {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,3 +68,28 @@ func TestProviderAddrs(t *testing.T) {
|
||||||
t.Error(problem)
|
t.Error(problem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Module outputs should not effect the result of Empty
|
||||||
|
func TestModuleOutputChangesEmpty(t *testing.T) {
|
||||||
|
changes := &Changes{
|
||||||
|
Outputs: []*OutputChangeSrc{
|
||||||
|
{
|
||||||
|
Addr: addrs.AbsOutputValue{
|
||||||
|
Module: addrs.RootModuleInstance.Child("child", addrs.NoKey),
|
||||||
|
OutputValue: addrs.OutputValue{
|
||||||
|
Name: "output",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ChangeSrc: ChangeSrc{
|
||||||
|
Action: Update,
|
||||||
|
Before: []byte("a"),
|
||||||
|
After: []byte("b"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if !changes.Empty() {
|
||||||
|
t.Fatal("plan has no visible changes")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue