terraform: module output variables are functional

This commit is contained in:
Mitchell Hashimoto 2014-09-23 16:07:41 -07:00
parent 1b5d0ed0bb
commit bfa4e1d7d0
3 changed files with 68 additions and 11 deletions

View File

@ -463,11 +463,6 @@ func (c *walkContext) Walk() error {
return err
}
// If we're not applying, we're done.
if c.Operation != walkApply {
return nil
}
// We did an apply, so we need to calculate the outputs. If we have no
// outputs, then we're done.
m := c.Context.module
@ -475,6 +470,9 @@ func (c *walkContext) Walk() error {
cs := m.Children()
m = cs[n]
}
if m == nil {
return nil
}
config := m.Config()
if len(config.Outputs) == 0 {
return nil
@ -483,7 +481,10 @@ func (c *walkContext) Walk() error {
// Likewise, if we have no resources in our state, we're done. This
// guards against the case that we destroyed.
mod := c.Context.state.ModuleByPath(c.Path)
mod.prune()
if c.Operation == walkApply {
// On Apply, we prune so that we don't do outputs if we destroyed
mod.prune()
}
if len(mod.Resources) == 0 {
return nil
}
@ -493,7 +494,10 @@ func (c *walkContext) Walk() error {
if err := c.computeVars(o.RawConfig); err != nil {
return err
}
outputs[o.Name] = o.RawConfig.Config()["value"].(string)
vraw := o.RawConfig.Config()["value"]
if vraw != nil {
outputs[o.Name] = vraw.(string)
}
}
// Assign the outputs to the root module
@ -1052,6 +1056,13 @@ func (c *walkContext) computeVars(raw *config.RawConfig) error {
// Next, the actual computed variables
for n, rawV := range raw.Variables {
switch v := rawV.(type) {
case *config.ModuleVariable:
value, err := c.computeModuleVariable(v)
if err != nil {
return err
}
vs[n] = value
case *config.ResourceVariable:
var attr string
var err error
@ -1086,6 +1097,37 @@ func (c *walkContext) computeVars(raw *config.RawConfig) error {
return raw.Interpolate(vs)
}
func (c *walkContext) computeModuleVariable(
v *config.ModuleVariable) (string, error) {
// Build the path to our child
path := make([]string, len(c.Path), len(c.Path)+1)
copy(path, c.Path)
path = append(path, v.Name)
// Grab some locks
c.Context.sl.RLock()
defer c.Context.sl.RUnlock()
// Get that module from our state
mod := c.Context.state.ModuleByPath(path)
if mod == nil {
return "", fmt.Errorf(
"Module '%s' not found for variable '%s'",
strings.Join(path[1:], "."),
v.FullKey())
}
value, ok := mod.Outputs[v.Field]
if !ok {
return "", fmt.Errorf(
"Output field '%s' not found for variable '%s'",
v.Field,
v.FullKey())
}
return value, nil
}
func (c *walkContext) computeResourceVariable(
v *config.ResourceVariable) (string, error) {
id := v.ResourceId()
@ -1097,8 +1139,7 @@ func (c *walkContext) computeResourceVariable(
defer c.Context.sl.RUnlock()
// Get the relevant module
// TODO: Not use only root module
module := c.Context.state.RootModule()
module := c.Context.state.ModuleByPath(c.Path)
r, ok := module.Resources[id]
if !ok {

View File

@ -1491,7 +1491,6 @@ func TestContextPlan_moduleOrphans(t *testing.T) {
}
func TestContextPlan_moduleVar(t *testing.T) {
t.Skip()
m := testModule(t, "plan-module-var")
p := testProvider("aws")
p.DiffFn = testDiffFn
@ -1508,7 +1507,7 @@ func TestContextPlan_moduleVar(t *testing.T) {
}
actual := strings.TrimSpace(plan.String())
expected := strings.TrimSpace(testTerraformPlanModulesStr)
expected := strings.TrimSpace(testTerraformPlanModuleVarStr)
if actual != expected {
t.Fatalf("bad:\n%s", actual)
}

View File

@ -528,6 +528,23 @@ module.child:
ID = baz
`
const testTerraformPlanModuleVarStr = `
DIFF:
CREATE: aws_instance.bar
foo: "" => "2"
type: "" => "aws_instance"
module.child:
CREATE: aws_instance.foo
num: "" => "2"
type: "" => "aws_instance"
STATE:
<no state>
`
const testTerraformPlanOrphanStr = `
DIFF: