-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
core: Add
terraform state rm
command and docs
This commit adds the `state rm` command for removing an address from state. It is the result of a rebase from pull-request #5953 which was lost at some point during the Terraform 0.7 feature branch merges.
- Loading branch information
Showing
5 changed files
with
293 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package command | ||
|
||
import ( | ||
"fmt" | ||
"strings" | ||
|
||
"github.com/mitchellh/cli" | ||
) | ||
|
||
// StateRmCommand is a Command implementation that shows a single resource. | ||
type StateRmCommand struct { | ||
Meta | ||
StateMeta | ||
} | ||
|
||
func (c *StateRmCommand) Run(args []string) int { | ||
args = c.Meta.process(args, true) | ||
|
||
var backupPath string | ||
cmdFlags := c.Meta.flagSet("state show") | ||
cmdFlags.StringVar(&backupPath, "backup", "", "backup") | ||
cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path") | ||
if err := cmdFlags.Parse(args); err != nil { | ||
return cli.RunResultHelp | ||
} | ||
args = cmdFlags.Args() | ||
|
||
state, err := c.StateMeta.State(&c.Meta) | ||
if err != nil { | ||
c.Ui.Error(fmt.Sprintf(errStateLoadingState, err)) | ||
return cli.RunResultHelp | ||
} | ||
|
||
stateReal := state.State() | ||
if stateReal == nil { | ||
c.Ui.Error(fmt.Sprintf(errStateNotFound)) | ||
return 1 | ||
} | ||
|
||
if err := stateReal.Remove(args...); err != nil { | ||
c.Ui.Error(fmt.Sprintf(errStateRm, err)) | ||
return 1 | ||
} | ||
|
||
if err := state.WriteState(stateReal); err != nil { | ||
c.Ui.Error(fmt.Sprintf(errStateRmPersist, err)) | ||
return 1 | ||
} | ||
|
||
if err := state.PersistState(); err != nil { | ||
c.Ui.Error(fmt.Sprintf(errStateRmPersist, err)) | ||
return 1 | ||
} | ||
|
||
c.Ui.Output("Item removal successful.") | ||
return 0 | ||
} | ||
|
||
func (c *StateRmCommand) Help() string { | ||
helpText := ` | ||
Usage: terraform state rm [options] ADDRESS... | ||
Remove one or more items from the Terraform state. | ||
This command removes one or more items from the Terraform state based | ||
on the address given. You can view and list the available resources | ||
with "terraform state list". | ||
This command creates a timestamped backup of the state on every invocation. | ||
This can't be disabled. Due to the destructive nature of this command, | ||
the backup is ensured by Terraform for safety reasons. | ||
Options: | ||
-backup=PATH Path where Terraform should write the backup | ||
state. This can't be disabled. If not set, Terraform | ||
will write it to the same path as the statefile with | ||
a backup extension. | ||
-state=statefile Path to a Terraform state file to use to look | ||
up Terraform-managed resources. By default it will | ||
use the state "terraform.tfstate" if it exists. | ||
` | ||
return strings.TrimSpace(helpText) | ||
} | ||
|
||
func (c *StateRmCommand) Synopsis() string { | ||
return "Remove an item from the state" | ||
} | ||
|
||
const errStateRm = `Error removing items from the state: %s | ||
The state was not saved. No items were removed from the persisted | ||
state. No backup was created since no modification occurred. Please | ||
resolve the issue above and try again.` | ||
|
||
const errStateRmPersist = `Error saving the state: %s | ||
The state was not saved. No items were removed from the persisted | ||
state. No backup was created since no modification occurred. Please | ||
resolve the issue above and try again.` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
package command | ||
|
||
import ( | ||
"path/filepath" | ||
"sort" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/terraform" | ||
"github.com/mitchellh/cli" | ||
) | ||
|
||
func TestStateRm(t *testing.T) { | ||
state := &terraform.State{ | ||
Modules: []*terraform.ModuleState{ | ||
&terraform.ModuleState{ | ||
Path: []string{"root"}, | ||
Resources: map[string]*terraform.ResourceState{ | ||
"test_instance.foo": &terraform.ResourceState{ | ||
Type: "test_instance", | ||
Primary: &terraform.InstanceState{ | ||
ID: "bar", | ||
Attributes: map[string]string{ | ||
"foo": "value", | ||
"bar": "value", | ||
}, | ||
}, | ||
}, | ||
|
||
"test_instance.bar": &terraform.ResourceState{ | ||
Type: "test_instance", | ||
Primary: &terraform.InstanceState{ | ||
ID: "foo", | ||
Attributes: map[string]string{ | ||
"foo": "value", | ||
"bar": "value", | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
statePath := testStateFile(t, state) | ||
|
||
p := testProvider() | ||
ui := new(cli.MockUi) | ||
c := &StateRmCommand{ | ||
Meta: Meta{ | ||
ContextOpts: testCtxConfig(p), | ||
Ui: ui, | ||
}, | ||
} | ||
|
||
args := []string{ | ||
"-state", statePath, | ||
"test_instance.foo", | ||
} | ||
if code := c.Run(args); code != 0 { | ||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) | ||
} | ||
|
||
// Test it is correct | ||
testStateOutput(t, statePath, testStateRmOutput) | ||
|
||
// Test we have backups | ||
backups := testStateBackups(t, filepath.Dir(statePath)) | ||
if len(backups) != 1 { | ||
t.Fatalf("bad: %#v", backups) | ||
} | ||
testStateOutput(t, backups[0], testStateRmOutputOriginal) | ||
} | ||
|
||
func TestStateRm_noState(t *testing.T) { | ||
tmp, cwd := testCwd(t) | ||
defer testFixCwd(t, tmp, cwd) | ||
|
||
p := testProvider() | ||
ui := new(cli.MockUi) | ||
c := &StateRmCommand{ | ||
Meta: Meta{ | ||
ContextOpts: testCtxConfig(p), | ||
Ui: ui, | ||
}, | ||
} | ||
|
||
args := []string{} | ||
if code := c.Run(args); code != 1 { | ||
t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) | ||
} | ||
} | ||
|
||
func testStateBackups(t *testing.T, dir string) []string { | ||
matches, err := filepath.Glob(filepath.Join(dir, "*.backup")) | ||
if err != nil { | ||
t.Fatalf("err: %s", err) | ||
} | ||
|
||
sort.Strings(matches) | ||
return matches | ||
} | ||
|
||
const testStateRmOutputOriginal = ` | ||
test_instance.bar: | ||
ID = foo | ||
bar = value | ||
foo = value | ||
test_instance.foo: | ||
ID = bar | ||
bar = value | ||
foo = value | ||
` | ||
|
||
const testStateRmOutput = ` | ||
test_instance.bar: | ||
ID = foo | ||
bar = value | ||
foo = value | ||
` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
--- | ||
layout: "commands-state" | ||
page_title: "Command: state rm" | ||
sidebar_current: "docs-state-sub-rm" | ||
description: |- | ||
The `terraform state rm` command removes items from the Terraform state. | ||
--- | ||
|
||
# Command: state rm | ||
|
||
The `terraform state rm` command is used to remove items from the | ||
[Terraform state](/docs/state/index.html). This command can remove | ||
single resources, since instances of a resource, entire modules, | ||
and more. | ||
|
||
## Usage | ||
|
||
Usage: `terraform state rm [options] ADDRESS...` | ||
|
||
The command will remove all the items matched by the addresses given. | ||
|
||
Items removed from the Terraform state are _not physically destroyed_. | ||
Items removed from the Terraform state are only no longer managed by | ||
Terraform. For example, if you remove an AWS instance from the state, the AWS | ||
instance will continue running, but `terraform plan` will no longer see that | ||
instance. | ||
|
||
There are various use cases for removing items from a Terraform state | ||
file. The most common is refactoring a configuration to no longer manage | ||
that resource (perhaps moving it to another Terraform configuration/state). | ||
|
||
The state will only be saved on successful removal of all addresses. | ||
If any specific address errors for any reason (such as a syntax error), | ||
the state will not be modified at all. | ||
|
||
This command will output a backup copy of the state prior to saving any | ||
changes. The backup cannot be disabled. Due to the destructive nature | ||
of this command, backups are required. | ||
|
||
This command requires one or more addresses that point to a resources in the | ||
state. Addresses are | ||
in [resource addressing format](/docs/commands/state/addressing.html). | ||
|
||
The command-line flags are all optional. The list of available flags are: | ||
|
||
* `-backup=path` - Path to a backup file Defaults to the state path plus | ||
a timestamp with the ".backup" extension. | ||
|
||
* `-state=path` - Path to the state file. Defaults to "terraform.tfstate". | ||
|
||
## Example: Remove a Resource | ||
|
||
The example below removes a single resource in a module: | ||
|
||
``` | ||
$ terraform state rm module.foo.packet_device.worker[0] | ||
``` | ||
|
||
## Example: Remove a Module | ||
|
||
The example below removes an entire module: | ||
|
||
``` | ||
$ terraform state rm module.foo | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters