diff --git a/command/state_mv.go b/command/state_mv.go index 7ca5fdd4b..b16f99828 100644 --- a/command/state_mv.go +++ b/command/state_mv.go @@ -79,13 +79,16 @@ func (c *StateMvCommand) Run(args []string) int { return 1 } + // Get the item to add to the state + add := c.addableResult(results) + // Do the actual move if err := stateFromReal.Remove(args[0]); err != nil { c.Ui.Error(fmt.Sprintf(errStateMv, err)) return 1 } - if err := stateToReal.Add(args[0], args[1], results[0].Value); err != nil { + if err := stateToReal.Add(args[0], args[1], add); err != nil { c.Ui.Error(fmt.Sprintf(errStateMv, err)) return 1 } @@ -119,6 +122,29 @@ func (c *StateMvCommand) Run(args []string) int { return 0 } +// addableResult takes the result from a filter operation and returns what to +// call State.Add with. The reason we do this is beacuse in the module case +// we must add the list of all modules returned versus just the root module. +func (c *StateMvCommand) addableResult(results []*terraform.StateFilterResult) interface{} { + switch v := results[0].Value.(type) { + case *terraform.ModuleState: + // If a module state then we should add the full list of modules + result := []*terraform.ModuleState{v} + if len(results) > 1 { + for _, r := range results[1:] { + if ms, ok := r.Value.(*terraform.ModuleState); ok { + result = append(result, ms) + } + } + } + + return result + default: + // By default just add the first result + return v + } +} + func (c *StateMvCommand) Help() string { helpText := ` Usage: terraform state mv [options] ADDRESS ADDRESS diff --git a/command/state_mv_test.go b/command/state_mv_test.go index 4cca8fbda..bec0504aa 100644 --- a/command/state_mv_test.go +++ b/command/state_mv_test.go @@ -327,6 +327,7 @@ test_instance.baz: ` const testStateMvNestedModule_stateOut = ` + module.bar: module.bar.child1: diff --git a/terraform/state_add.go b/terraform/state_add.go index 54a5732a5..5aa795748 100644 --- a/terraform/state_add.go +++ b/terraform/state_add.go @@ -129,7 +129,7 @@ func stateAddFunc_Module_Module(s *State, fromAddr, addr *ResourceAddress, raw i } // It is! Strip the leading prefix and attach that to our address - extra := item.Path[len(src.Path)+1:] + extra := item.Path[len(src.Path):] addrCopy := addr.Copy() addrCopy.Path = append(addrCopy.Path, extra...) diff --git a/terraform/state_add_test.go b/terraform/state_add_test.go index 4ecf5aab0..4270ccc03 100644 --- a/terraform/state_add_test.go +++ b/terraform/state_add_test.go @@ -201,7 +201,7 @@ func TestStateAdd(t *testing.T) { []*ModuleState{ &ModuleState{ - Path: rootModulePath, + Path: []string{"root", "foo"}, Resources: map[string]*ResourceState{}, },