Support reading module outputs in terraform console (#24808)

* Include eval in output walk

This allows outputs to be evaluated in the evalwalk,
impacting terraform console. Outputs are still not evaluated
for terraform console in the root module, so this has
no impact on writing to state (as child module outputs are not
written to state). Also adds test coverage to the console command,
including for evaluating locals (another use of the evalwalk)
This commit is contained in:
Pam Selle 2020-04-30 09:21:42 -04:00 committed by GitHub
parent 67f66ee970
commit 87bce5f9dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 86 additions and 1 deletions

View File

@ -3,10 +3,12 @@ package command
import ( import (
"bytes" "bytes"
"io/ioutil" "io/ioutil"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
"testing" "testing"
"github.com/hashicorp/terraform/helper/copy"
"github.com/mitchellh/cli" "github.com/mitchellh/cli"
) )
@ -133,3 +135,46 @@ func TestConsole_unsetRequiredVars(t *testing.T) {
t.Fatalf("wrong output\ngot:\n%s\n\nwant string containing %q", got, want) t.Fatalf("wrong output\ngot:\n%s\n\nwant string containing %q", got, want)
} }
} }
func TestConsole_modules(t *testing.T) {
td := tempDir(t)
copy.CopyDir(testFixturePath("modules"), td)
defer os.RemoveAll(td)
defer testChdir(t, td)()
p := testProvider()
ui := new(cli.MockUi)
c := &ConsoleCommand{
Meta: Meta{
testingOverrides: metaOverridesForProvider(p),
Ui: ui,
},
}
commands := map[string]string{
"module.child.myoutput\n": "bar\n",
"module.count_child[0].myoutput\n": "bar\n",
"local.foo\n": "3\n",
}
args := []string{
testFixturePath("modules"),
}
for cmd, val := range commands {
var output bytes.Buffer
defer testStdinPipe(t, strings.NewReader(cmd))()
outCloser := testStdoutCapture(t, &output)
code := c.Run(args)
outCloser()
if code != 0 {
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String())
}
actual := output.String()
if output.String() != val {
t.Fatalf("bad: %q, expected %q", actual, val)
}
}
}

View File

@ -0,0 +1 @@
{"Modules":[{"Key":"","Source":"","Dir":"."},{"Key":"child","Source":"./child","Dir":"child"},{"Key":"count_child","Source":"./child","Dir":"child"}]}

View File

@ -0,0 +1,5 @@
resource "test_instance" "test" {
}
output "myoutput" {
value = "bar"
}

11
command/testdata/modules/main.tf vendored Normal file
View File

@ -0,0 +1,11 @@
locals {
foo = 3
}
module "child" {
source = "./child"
}
module "count_child" {
count = 1
source = "./child"
}

View File

@ -0,0 +1,23 @@
{
"version": 4,
"terraform_version": "0.13.0",
"serial": 7,
"lineage": "9cb740e3-d64d-e53e-a8e4-99b9bcacf24b",
"outputs": {},
"resources": [
{
"module": "module.child",
"mode": "managed",
"type": "test_instance",
"name": "test",
"provider": "provider[\"registry.terraform.io/hashicorp/test\"]",
"instances": [
{
"schema_version": 0,
"attributes": {}
}
]
}
]
}

View File

@ -222,7 +222,7 @@ func (n *NodeApplyableOutput) EvalTree() EvalNode {
return &EvalSequence{ return &EvalSequence{
Nodes: []EvalNode{ Nodes: []EvalNode{
&EvalOpFilter{ &EvalOpFilter{
Ops: []walkOperation{walkRefresh, walkPlan, walkApply, walkValidate, walkDestroy, walkPlanDestroy}, Ops: []walkOperation{walkEval, walkRefresh, walkPlan, walkApply, walkValidate, walkDestroy, walkPlanDestroy},
Node: &EvalWriteOutput{ Node: &EvalWriteOutput{
Addr: n.Addr.OutputValue, Addr: n.Addr.OutputValue,
Sensitive: n.Config.Sensitive, Sensitive: n.Config.Sensitive,