diff --git a/command/init_test.go b/command/init_test.go index 6030b877e..295098c62 100644 --- a/command/init_test.go +++ b/command/init_test.go @@ -321,6 +321,38 @@ func TestInit_backendConfigFile(t *testing.T) { } } +func TestInit_backendConfigFileChange(t *testing.T) { + // Create a temporary working directory that is empty + td := tempDir(t) + copy.CopyDir(testFixturePath("init-backend-config-file-change"), td) + defer os.RemoveAll(td) + defer testChdir(t, td)() + + // Ask input + defer testInputMap(t, map[string]string{ + "backend-migrate-to-new": "no", + })() + + ui := new(cli.MockUi) + c := &InitCommand{ + Meta: Meta{ + ContextOpts: testCtxConfig(testProvider()), + Ui: ui, + }, + } + + args := []string{"-backend-config", "input.config"} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) + } + + // Read our saved backend config and verify we have our settings + state := testStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) + if v := state.Backend.Config["path"]; v != "hello" { + t.Fatalf("bad: %#v", v) + } +} + func TestInit_copyBackendDst(t *testing.T) { // Create a temporary working directory that is empty td := tempDir(t) diff --git a/command/meta_backend.go b/command/meta_backend.go index 31dc9b566..f1ad37190 100644 --- a/command/meta_backend.go +++ b/command/meta_backend.go @@ -302,6 +302,16 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, error) { return nil, fmt.Errorf("Error loading backend config: %s", err) } + // cHash defaults to zero unless c is set + var cHash uint64 + if c != nil { + // We need to rehash to get the value since we may have merged the + // config with an extra ConfigFile. We don't do this when merging + // because we do want the ORIGINAL value on c so that we store + // that to not detect drift. This is covered in tests. + cHash = c.Rehash() + } + // Get the path to where we store a local cache of backend configuration // if we're using a remote backend. This may not yet exist which means // we haven't used a non-local backend before. That is okay. @@ -384,7 +394,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, error) { case c != nil && s.Remote.Empty() && !s.Backend.Empty(): // If our configuration is the same, then we're just initializing // a previously configured remote backend. - if !s.Backend.Empty() && s.Backend.Hash == c.Hash { + if !s.Backend.Empty() && s.Backend.Hash == cHash { return m.backend_C_r_S_unchanged(c, sMgr) } @@ -398,7 +408,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, error) { log.Printf( "[WARN] command: backend config change! saved: %d, new: %d", - s.Backend.Hash, c.Hash) + s.Backend.Hash, cHash) return m.backend_C_r_S_changed(c, sMgr, true) // Configuring a backend for the first time while having legacy @@ -420,7 +430,7 @@ func (m *Meta) backendFromConfig(opts *BackendOpts) (backend.Backend, error) { case c != nil && !s.Remote.Empty() && !s.Backend.Empty(): // If the hashes are the same, we have a legacy remote state with // an unchanged stored backend state. - if s.Backend.Hash == c.Hash { + if s.Backend.Hash == cHash { if !opts.Init { initReason := fmt.Sprintf( "Legacy remote state found with configured backend %q", diff --git a/command/test-fixtures/init-backend-config-file-change/.terraform/terraform.tfstate b/command/test-fixtures/init-backend-config-file-change/.terraform/terraform.tfstate new file mode 100644 index 000000000..073bd7a82 --- /dev/null +++ b/command/test-fixtures/init-backend-config-file-change/.terraform/terraform.tfstate @@ -0,0 +1,22 @@ +{ + "version": 3, + "serial": 0, + "lineage": "666f9301-7e65-4b19-ae23-71184bb19b03", + "backend": { + "type": "local", + "config": { + "path": "local-state.tfstate" + }, + "hash": 9073424445967744180 + }, + "modules": [ + { + "path": [ + "root" + ], + "outputs": {}, + "resources": {}, + "depends_on": [] + } + ] +} diff --git a/command/test-fixtures/init-backend-config-file-change/input.config b/command/test-fixtures/init-backend-config-file-change/input.config new file mode 100644 index 000000000..6cd14f4a3 --- /dev/null +++ b/command/test-fixtures/init-backend-config-file-change/input.config @@ -0,0 +1 @@ +path = "hello" diff --git a/command/test-fixtures/init-backend-config-file-change/main.tf b/command/test-fixtures/init-backend-config-file-change/main.tf new file mode 100644 index 000000000..ca1bd3921 --- /dev/null +++ b/command/test-fixtures/init-backend-config-file-change/main.tf @@ -0,0 +1,5 @@ +terraform { + backend "local" { + path = "local-state.tfstate" + } +}