terraform: module variable transform must do children later (tested)

This commit is contained in:
Mitchell Hashimoto 2016-09-23 09:19:09 -07:00
parent c1664d2eaa
commit 924f7a49e0
No known key found for this signature in database
GPG Key ID: 744E147AA52F5B0A
8 changed files with 109 additions and 4 deletions

View File

@ -3094,6 +3094,8 @@ func TestContext2Apply_destroyModuleWithAttrsReferencingResource(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("apply err: %s", err) t.Fatalf("apply err: %s", err)
} }
t.Logf("Step 1 state: %s", state)
} }
h := new(HookRecordApplyOrder) h := new(HookRecordApplyOrder)

View File

@ -0,0 +1,3 @@
variable "value" {}
output "result" { value = "${var.value}" }

View File

@ -0,0 +1,4 @@
module "child" {
source = "./child"
value = "foo"
}

View File

@ -0,0 +1,3 @@
variable "value" {}
output "result" { value = "${var.value}" }

View File

@ -0,0 +1,6 @@
variable "value" {}
module "child" {
source = "./child"
value = "${var.value}"
}

View File

@ -0,0 +1,4 @@
module "child" {
source = "./child"
value = "foo"
}

View File

@ -28,15 +28,32 @@ func (t *ModuleVariableTransformer) transform(g *Graph, parent, m *module.Tree)
return nil return nil
} }
// Transform all the children. // If we have no parent, then don't do anything. This is because
// we need to be able to get the set value from the module declaration.
if err := t.transformSingle(g, parent, m); err != nil {
return nil
}
// Transform all the children. This has to be _after_ the above
// since children can reference parent variables but parents can't
// access children. Example:
//
// module foo { value = "${var.foo}" }
//
// The "value" var in "foo" (a child) is accessing the "foo" bar
// in the parent (current module). However, there is no way for the
// current module to reference a variable in the child module.
for _, c := range m.Children() { for _, c := range m.Children() {
if err := t.transform(g, m, c); err != nil { if err := t.transform(g, m, c); err != nil {
return err return err
} }
} }
// If we have no parent, then don't do anything. This is because return nil
// we need to be able to get the set value from the module declaration. }
func (t *ModuleVariableTransformer) transformSingle(g *Graph, parent, m *module.Tree) error {
// If we have no parent, we can't determine if the parent uses our variables
if parent == nil { if parent == nil {
return nil return nil
} }
@ -44,6 +61,7 @@ func (t *ModuleVariableTransformer) transform(g *Graph, parent, m *module.Tree)
// If we have no vars, we're done! // If we have no vars, we're done!
vars := m.Config().Variables vars := m.Config().Variables
if len(vars) == 0 { if len(vars) == 0 {
log.Printf("[TRACE] Module %#v has no variables, skipping.", m.Path())
return nil return nil
} }
@ -56,7 +74,7 @@ func (t *ModuleVariableTransformer) transform(g *Graph, parent, m *module.Tree)
} }
} }
if mod == nil { if mod == nil {
log.Printf("[INFO] Module %q not used, not adding variables", m.Name()) log.Printf("[INFO] Module %#v not used, not adding variables", m.Path())
return nil return nil
} }

View File

@ -0,0 +1,65 @@
package terraform
import (
"strings"
"testing"
)
func TestModuleVariableTransformer(t *testing.T) {
g := Graph{Path: RootModulePath}
module := testModule(t, "transform-module-var-basic")
{
tf := &RootVariableTransformer{Module: module}
if err := tf.Transform(&g); err != nil {
t.Fatalf("err: %s", err)
}
}
{
tf := &ModuleVariableTransformer{Module: module}
if err := tf.Transform(&g); err != nil {
t.Fatalf("err: %s", err)
}
}
actual := strings.TrimSpace(g.String())
expected := strings.TrimSpace(testTransformModuleVarBasicStr)
if actual != expected {
t.Fatalf("bad:\n\n%s", actual)
}
}
func TestModuleVariableTransformer_nested(t *testing.T) {
g := Graph{Path: RootModulePath}
module := testModule(t, "transform-module-var-nested")
{
tf := &RootVariableTransformer{Module: module}
if err := tf.Transform(&g); err != nil {
t.Fatalf("err: %s", err)
}
}
{
tf := &ModuleVariableTransformer{Module: module}
if err := tf.Transform(&g); err != nil {
t.Fatalf("err: %s", err)
}
}
actual := strings.TrimSpace(g.String())
expected := strings.TrimSpace(testTransformModuleVarNestedStr)
if actual != expected {
t.Fatalf("bad:\n\n%s", actual)
}
}
const testTransformModuleVarBasicStr = `
module.child.var.value
`
const testTransformModuleVarNestedStr = `
module.child.module.child.var.value
module.child.var.value
`