Skip to content

Commit

Permalink
Switch to using json file for bulk import
Browse files Browse the repository at this point in the history
  • Loading branch information
tmccombs committed Oct 28, 2021
1 parent 9b10f97 commit 4351de0
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 51 deletions.
33 changes: 14 additions & 19 deletions internal/command/import.go
@@ -1,7 +1,7 @@
package command

import (
"bufio"
"encoding/json"
"errors"
"fmt"
"io"
Expand Down Expand Up @@ -84,27 +84,22 @@ func (c *ImportCommand) importBulk(configPath string, importFile string) int {
return 1
}
}
decoder := json.NewDecoder(input)
var mapping map[string]string
err = decoder.Decode(&mapping)
if err != nil {
c.Ui.Error(fmt.Sprintf("Unable to parse JSON: %s", err))
return 1
}

var targets []*terraform.ImportTarget
scanner := bufio.NewScanner(input)
for scanner.Scan() {
line := strings.Trim(scanner.Text(), " ")
// This assumes that there aren't any spaces in the ID. But as far
// as I know, that is a good assumption.
splitIdx := strings.LastIndex(line, " ")
if splitIdx < 0 {
c.Ui.Error("Each line of input must be a resource and id seperated by a space.")
return 1
}
target, ok := c.getTarget(line[:splitIdx], line[splitIdx+1:])
for addr, id := range mapping {
target, ok := c.getTarget(addr, id)
if !ok {
return 1
}
targets = append(targets, target)
}
if err = scanner.Err(); err != nil {
c.Ui.Error(fmt.Sprintf("Error reading input: %s.", err))
return 1
}

return c.importTargets(configPath, targets)
}
Expand Down Expand Up @@ -390,9 +385,9 @@ Options:
-bulk=path Import resources in bulk from a file. If this option is
supplied, then ADDR and ID should not be given on the
command line. Instead, the file at the path should
contain lines with addresses and ids seperated by a
space on each line. A path of "-" will cause it to
command line. Instead, the file at the path should be a
JSON file with a single object mapping the resource name
to the id to import. A path of "-" will cause it to
read from stdin.
-input=false Disable interactive input prompts.
Expand Down
23 changes: 1 addition & 22 deletions internal/command/import_test.go
Expand Up @@ -1038,12 +1038,6 @@ func TestImport_bulk(t *testing.T) {
defer testChdir(t, testFixturePath("import-bulk"))()

statePath := testTempFile(t)
bulkPath := testBulkImportFile(t, map[string]string{
"test_instance.test1": "abc",
"test_instance.test2": "123",
"test_instance.test3": "alpha",
})
defer os.Remove(bulkPath)

p := testProvider()
ui := new(cli.MockUi)
Expand Down Expand Up @@ -1077,7 +1071,7 @@ func TestImport_bulk(t *testing.T) {

args := []string{
"-state", statePath,
"-bulk", bulkPath,
"-bulk", "import.json",
}

if code := c.Run(args); code != 0 {
Expand All @@ -1087,21 +1081,6 @@ func TestImport_bulk(t *testing.T) {
testStateOutput(t, statePath, testBulkImportStr)
}

func testBulkImportFile(t *testing.T, imports map[string]string) string {
t.Helper()
f, err := ioutil.TempFile(testingDir, "import")
if err != nil {
t.Fatalf("err: %s", err)
}
defer f.Close()

for name, id := range imports {
fmt.Fprintf(f, "%s %s\n", name, id)
}

return f.Name()
}

const testImportStr = `
test_instance.foo:
ID = yay
Expand Down
5 changes: 5 additions & 0 deletions internal/command/testdata/import-bulk/import.json
@@ -0,0 +1,5 @@
{
"test_instance.test1": "abc",
"test_instance.test2": "123",
"test_instance.test3": "alpha"
}
8 changes: 4 additions & 4 deletions website/docs/cli/commands/import.html.md
Expand Up @@ -38,16 +38,16 @@ If you import the same object multiple times, Terraform may exhibit unwanted
behavior. For more information on this assumption, see
[the State section](/docs/language/state/index.html).

When importing numerous resources, it is more efficient ot use the `-bulk` option
When importing numerous resources, it is more efficient to use the `-bulk` option
to import many resources at once, rather than needing to modify the state for each
resource individually.

The command-line flags are all optional. The list of available flags are:

* `-bulk=path` - Import resources in bulk from a file. If this option is
* `-bulk=path` - Import resources in bulk from a file. If this option is
supplied, then ADDR and ID should not be given on the command line. Instead,
the file at the path should contain lines with addresses and ids seperated by a
space on each line.
the file at the path should be a JSON file with a single object mapping the
resource name to the id to import.

* `-config=path` - Path to directory of Terraform configuration files that
configure the provider for import. This defaults to your working directory.
Expand Down
15 changes: 9 additions & 6 deletions website/docs/cli/import/usage.html.md
Expand Up @@ -75,12 +75,15 @@ align with the current (or desired) state of the imported object.
When importing many resources, it is more efficient to import all the
resources witha single command. This allows the state to be updated just once
for all resources, rather than once for each resource. To do this create
an import file that has the resource and id pairs, for example:

```
aws_instance.example1 i-abcd1234
aws_instance.example2 i-1234abcd
aws_instance.example3 i-12345abc
a json file that has a map from the resource address to the appropriate id.
For example:

```json
{
"aws_instance.example1": "i-abcd1234",
"aws_instance.example2": "i-1234abcd",
"aws_instance.example3": "i-12345abc"
}
```

Then you can run `terraform import` with the `-bulk` option:
Expand Down

0 comments on commit 4351de0

Please sign in to comment.