Skip to content

Commit 3114e2a

Browse files
authored
Merge pull request #25890 from hashicorp/import-our-nemesis
terraform: Eval module call arguments for import
2 parents 7ef4e7f + d8e9964 commit 3114e2a

File tree

5 files changed

+91
-1
lines changed

5 files changed

+91
-1
lines changed

command/import_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,76 @@ func TestImportModuleVarFile(t *testing.T) {
802802
}
803803
}
804804

805+
// This test covers an edge case where a module with a complex input variable
806+
// of nested objects has an invalid default which is overridden by the calling
807+
// context, and is used in locals. If we don't evaluate module call variables
808+
// for the import walk, this results in an error.
809+
//
810+
// The specific example has a variable "foo" which is a nested object:
811+
//
812+
// foo = { bar = { baz = true } }
813+
//
814+
// This is used as foo = var.foo in the call to the child module, which then
815+
// uses the traversal foo.bar.baz in a local. A default value in the child
816+
// module of {} causes this local evaluation to error, breaking import.
817+
func TestImportModuleInputVariableEvaluation(t *testing.T) {
818+
td := tempDir(t)
819+
copy.CopyDir(testFixturePath("import-module-input-variable"), td)
820+
defer os.RemoveAll(td)
821+
defer testChdir(t, td)()
822+
823+
statePath := testTempFile(t)
824+
825+
p := testProvider()
826+
p.GetSchemaReturn = &terraform.ProviderSchema{
827+
ResourceTypes: map[string]*configschema.Block{
828+
"test_instance": {
829+
Attributes: map[string]*configschema.Attribute{
830+
"foo": {Type: cty.String, Optional: true},
831+
},
832+
},
833+
},
834+
}
835+
836+
providerSource, close := newMockProviderSource(t, map[string][]string{
837+
"test": {"1.2.3"},
838+
})
839+
defer close()
840+
841+
// init to install the module
842+
ui := new(cli.MockUi)
843+
m := Meta{
844+
testingOverrides: metaOverridesForProvider(testProvider()),
845+
Ui: ui,
846+
ProviderSource: providerSource,
847+
}
848+
849+
ic := &InitCommand{
850+
Meta: m,
851+
}
852+
if code := ic.Run([]string{}); code != 0 {
853+
t.Fatalf("init failed\n%s", ui.ErrorWriter)
854+
}
855+
856+
// import
857+
ui = new(cli.MockUi)
858+
c := &ImportCommand{
859+
Meta: Meta{
860+
testingOverrides: metaOverridesForProvider(p),
861+
Ui: ui,
862+
},
863+
}
864+
args := []string{
865+
"-state", statePath,
866+
"module.child.test_instance.foo",
867+
"bar",
868+
}
869+
code := c.Run(args)
870+
if code != 0 {
871+
t.Fatalf("import failed; expected success")
872+
}
873+
}
874+
805875
func TestImport_dataResource(t *testing.T) {
806876
defer testChdir(t, testFixturePath("import-missing-resource-config"))()
807877

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
variable "foo" {
2+
default = {}
3+
}
4+
5+
locals {
6+
baz = var.foo.bar.baz
7+
}
8+
9+
resource "test_instance" "foo" {
10+
foo = local.baz
11+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
variable "foo" {
2+
default = {}
3+
}
4+
5+
module "child" {
6+
source = "./child"
7+
foo = var.foo
8+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo = { bar = { baz = true } }

terraform/node_module_variable.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ func (n *nodeModuleVariable) EvalTree() EvalNode {
154154
Nodes: []EvalNode{
155155
&EvalOpFilter{
156156
Ops: []walkOperation{walkRefresh, walkPlan, walkApply,
157-
walkDestroy},
157+
walkDestroy, walkImport},
158158
Node: &EvalModuleCallArgument{
159159
Addr: n.Addr.Variable,
160160
Config: n.Config,

0 commit comments

Comments
 (0)