diff --git a/command/state_list.go b/command/state_list.go index 211f5b3d0..ba0bc9e38 100644 --- a/command/state_list.go +++ b/command/state_list.go @@ -23,6 +23,7 @@ func (c *StateListCommand) Run(args []string) int { cmdFlags := c.Meta.flagSet("state list") cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path") + lookupId := cmdFlags.String("id", "", "Restrict output to paths with a resource having the specified ID.") if err := cmdFlags.Parse(args); err != nil { return cli.RunResultHelp } @@ -62,8 +63,10 @@ func (c *StateListCommand) Run(args []string) int { } for _, result := range results { - if _, ok := result.Value.(*terraform.InstanceState); ok { - c.Ui.Output(result.Address) + if i, ok := result.Value.(*terraform.InstanceState); ok { + if *lookupId == "" || i.ID == *lookupId { + c.Ui.Output(result.Address) + } } } @@ -94,6 +97,8 @@ Options: up Terraform-managed resources. By default it will use the state "terraform.tfstate" if it exists. + -id=ID Restricts the output to objects whose id is ID. + ` return strings.TrimSpace(helpText) } diff --git a/command/state_list_test.go b/command/state_list_test.go index 4c484f09b..0d4cedd00 100644 --- a/command/state_list_test.go +++ b/command/state_list_test.go @@ -37,6 +37,65 @@ func TestStateList(t *testing.T) { } } +func TestStateListWithID(t *testing.T) { + state := testState() + statePath := testStateFile(t, state) + + p := testProvider() + ui := new(cli.MockUi) + c := &StateListCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: ui, + }, + } + + args := []string{ + "-state", statePath, + "-id", "bar", + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + // Test that outputs were displayed + expected := strings.TrimSpace(testStateListOutput) + "\n" + actual := ui.OutputWriter.String() + if actual != expected { + t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) + } +} + +func TestStateListWithNonExistentID(t *testing.T) { + state := testState() + statePath := testStateFile(t, state) + + p := testProvider() + ui := new(cli.MockUi) + c := &StateListCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(p), + Ui: ui, + }, + } + + args := []string{ + "-state", statePath, + "-id", "baz", + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + // Test that output is empty + if ui.OutputWriter != nil { + actual := ui.OutputWriter.String() + if actual != "" { + t.Fatalf("Expected an empty output but got: %q", actual) + } + } +} + func TestStateList_backendState(t *testing.T) { // Create a temporary working directory that is empty td := tempDir(t) diff --git a/website/docs/commands/state/list.html.md b/website/docs/commands/state/list.html.md index 9b8a6dadc..f18b3716b 100644 --- a/website/docs/commands/state/list.html.md +++ b/website/docs/commands/state/list.html.md @@ -31,6 +31,7 @@ The command-line flags are all optional. The list of available flags are: * `-state=path` - Path to the state file. Defaults to "terraform.tfstate". Ignored when [remote state](/docs/state/remote.html) is used. +* `-id=id` - ID of resources to show. Ignored when unset. ## Example: All Resources @@ -62,3 +63,14 @@ This example will only list resources in the given module: $ terraform state list module.elb module.elb.aws_elb.main ``` + +## Example: Filtering by ID + +This example will only list the resource whose ID is specified on the +command line. This is useful to find where in your configuration a +specific resource is located. + +``` +$ terraform state list -id=sg-1234abcd +module.elb.aws_security_group.sg +```