From f8ec7dad192d47e5933cbb83b5a4bea7ad513683 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 2 Nov 2016 11:11:42 -0700 Subject: [PATCH] command/import: allow the -config flag to specify a config location --- command/import.go | 22 +++++--- command/import_test.go | 57 +++++++++++++++++++++ website/source/docs/commands/import.html.md | 38 ++++++++++++-- website/source/docs/import/usage.html.md | 3 -- 4 files changed, 105 insertions(+), 15 deletions(-) diff --git a/command/import.go b/command/import.go index d17f38838..37cf708f4 100644 --- a/command/import.go +++ b/command/import.go @@ -16,6 +16,14 @@ type ImportCommand struct { } func (c *ImportCommand) Run(args []string) int { + // Get the pwd since its our default -config flag value + pwd, err := os.Getwd() + if err != nil { + c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err)) + return 1 + } + + var configPath string args = c.Meta.process(args, true) cmdFlags := c.Meta.flagSet("import") @@ -23,6 +31,7 @@ func (c *ImportCommand) Run(args []string) int { cmdFlags.StringVar(&c.Meta.statePath, "state", DefaultStateFilename, "path") cmdFlags.StringVar(&c.Meta.stateOutPath, "state-out", "", "path") cmdFlags.StringVar(&c.Meta.backupPath, "backup", "", "path") + cmdFlags.StringVar(&configPath, "config", pwd, "path") cmdFlags.Usage = func() { c.Ui.Error(c.Help()) } if err := cmdFlags.Parse(args); err != nil { return 1 @@ -35,15 +44,9 @@ func (c *ImportCommand) Run(args []string) int { return 1 } - pwd, err := os.Getwd() - if err != nil { - c.Ui.Error(fmt.Sprintf("Error getting pwd: %s", err)) - return 1 - } - // Build the context based on the arguments given ctx, _, err := c.Context(contextOpts{ - Path: pwd, + Path: configPath, PathEmptyOk: true, StatePath: c.Meta.statePath, Parallelism: c.Meta.parallelism, @@ -120,6 +123,11 @@ Options: modifying. Defaults to the "-state-out" path with ".backup" extension. Set to "-" to disable backup. + -config=path Path to a directory of Terraform configuration files + to use to configure the provider. Defaults to pwd. + If no config files are present, they must be provided + via the input prompts or env vars. + -input=true Ask for input for variables if not directly set. -no-color If specified, output won't contain any color. diff --git a/command/import_test.go b/command/import_test.go index 319388057..9e5129b54 100644 --- a/command/import_test.go +++ b/command/import_test.go @@ -102,6 +102,63 @@ func TestImport_providerConfig(t *testing.T) { testStateOutput(t, statePath, testImportStr) } +func TestImport_providerConfigDisable(t *testing.T) { + defer testChdir(t, testFixturePath("import-provider"))() + + statePath := testTempFile(t) + + p := testProvider() + ui := new(cli.MockUi) + c := &ImportCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(p), + Ui: ui, + }, + } + + p.ImportStateFn = nil + p.ImportStateReturn = []*terraform.InstanceState{ + &terraform.InstanceState{ + ID: "yay", + Ephemeral: terraform.EphemeralState{ + Type: "test_instance", + }, + }, + } + + configured := false + p.ConfigureFn = func(c *terraform.ResourceConfig) error { + configured = true + + if v, ok := c.Get("foo"); ok { + return fmt.Errorf("bad value: %#v", v) + } + + return nil + } + + args := []string{ + "-state", statePath, + "-config", "", + "test_instance.foo", + "bar", + } + if code := c.Run(args); code != 0 { + t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) + } + + // Verify that we were called + if !configured { + t.Fatal("Configure should be called") + } + + if !p.ImportStateCalled { + t.Fatal("ImportState should be called") + } + + testStateOutput(t, statePath, testImportStr) +} + /* func TestRefresh_badState(t *testing.T) { p := testProvider() diff --git a/website/source/docs/commands/import.html.md b/website/source/docs/commands/import.html.md index 470bfdeec..4f717b965 100644 --- a/website/source/docs/commands/import.html.md +++ b/website/source/docs/commands/import.html.md @@ -35,6 +35,11 @@ The command-line flags are all optional. The list of available flags are: the `-state-out` path with the ".backup" extension. Set to "-" to disable backups. +* `-config=path` - Path to directory of Terraform configuration files that + configure the provider for import. This defaults to your working directory. + If this directory contains no Terraform configuration files, the provider + must be configured via manual input or environmental variables. + * `-input=true` - Whether to ask for input for provider configuration. * `-state=path` - The path to read and save state files (unless state-out is @@ -46,12 +51,35 @@ The command-line flags are all optional. The list of available flags are: ## Provider Configuration -To access the provider that the resource is being imported from, Terraform -will ask you for access credentials. If you don't want to be asked for input, -verify that all environment variables for your provider are set. +Terraform will attempt to load configuration files that configure the +provider being used for import. If no configuration files are present or +no configuration for that specific provider is present, Terraform will +prompt you for access credentials. You may also specify environmental variables +to configure the provider. -The import command cannot read provider configuration from a Terraform -configuration file. +The only limitation Terraform has when reading the configuration files +is that the import provider configurations must not depend on non-variable +inputs. For example, a provider configuration cannot depend on a data +source. + +As a working example, if you're importing AWS resources and you have a +configuration file with the contents below, then Terraform will configure +the AWS provider with this file. + +``` +variable "access_key" {} +variable "secret_key" {} + +provider "aws" { + access_key = "${var.access_key}" + secret_key = "${var.secret_key}" +} +``` + +You can force Terraform to explicitly not load your configuration by +specifying `-config=""` (empty string). This is useful in situations where +you want to manually configure the provider because your configuration +may not be valid. ## Example: AWS Instance diff --git a/website/source/docs/import/usage.html.md b/website/source/docs/import/usage.html.md index 4eb3f8415..9ca563022 100644 --- a/website/source/docs/import/usage.html.md +++ b/website/source/docs/import/usage.html.md @@ -22,9 +22,6 @@ $ terraform import aws_instance.bar i-abcd1234 ... ``` -~> **Note:** In order to import resources, the provider should be configured with environment variables. -We currently do not support passing credentials directly to the provider. - The above command imports an AWS instance with the given ID to the address `aws_instance.bar`. You can also import resources into modules. See the [resource addressing](/docs/internals/resource-addressing.html)