From c017149b31fd82c40ccac65c2b1dfb814555818c Mon Sep 17 00:00:00 2001 From: James Bardin Date: Fri, 24 May 2019 14:51:18 -0400 Subject: [PATCH] don't store prepared backend config The backend gets to "prepare" the configuration before Configure is called, in order to validate the values and insert defaults. We don't want to store this value in the "config state", because it will often not match the raw config after it is prepared, forcing unecessary backend migrations during init. Since PrepareConfig is always called before Configure, we can store the config value directly, and assume that it will be prepared in the same manner each time. --- command/init_test.go | 46 +++++++++++++++++++++++++++++++++ command/meta_backend.go | 12 +++------ command/meta_backend_migrate.go | 1 - 3 files changed, 50 insertions(+), 9 deletions(-) diff --git a/command/init_test.go b/command/init_test.go index 6e5985944..bda5fe06e 100644 --- a/command/init_test.go +++ b/command/init_test.go @@ -456,6 +456,52 @@ func TestInit_backendConfigKVReInit(t *testing.T) { } } +func TestInit_backendConfigKVReInitWithConfigDiff(t *testing.T) { + // Create a temporary working directory that is empty + td := tempDir(t) + copy.CopyDir(testFixturePath("init-backend"), td) + defer os.RemoveAll(td) + defer testChdir(t, td)() + + ui := new(cli.MockUi) + c := &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + }, + } + + args := []string{"-input=false"} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) + } + + ui = new(cli.MockUi) + c = &InitCommand{ + Meta: Meta{ + testingOverrides: metaOverridesForProvider(testProvider()), + Ui: ui, + }, + } + + // a second init with identical config should require no changes, nor + // should it change the backend. + args = []string{"-input=false", "-backend-config", "path=foo"} + if code := c.Run(args); code != 0 { + t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) + } + + // make sure the backend is configured how we expect + configState := testDataStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename)) + cfg := map[string]interface{}{} + if err := json.Unmarshal(configState.Backend.ConfigRaw, &cfg); err != nil { + t.Fatal(err) + } + if cfg["path"] != "foo" { + t.Fatalf(`expected backend path="foo", got path="%v"`, cfg["foo"]) + } +} + func TestInit_targetSubdir(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 738a0b94f..205361cba 100644 --- a/command/meta_backend.go +++ b/command/meta_backend.go @@ -185,9 +185,8 @@ func (m *Meta) BackendForPlan(settings plans.Backend) (backend.Enhanced, tfdiags if validateDiags.HasErrors() { return nil, diags } - configVal = newVal - configureDiags := b.Configure(configVal) + configureDiags := b.Configure(newVal) diags = diags.Append(configureDiags) // If the backend supports CLI initialization, do it. @@ -922,9 +921,8 @@ func (m *Meta) backend_C_r_S_unchanged(c *configs.Backend, cHash int, sMgr *stat if validDiags.HasErrors() { return nil, diags } - configVal = newVal - configDiags := b.Configure(configVal) + configDiags := b.Configure(newVal) diags = diags.Append(configDiags) if configDiags.HasErrors() { return nil, diags @@ -1051,9 +1049,8 @@ func (m *Meta) backendInitFromConfig(c *configs.Backend) (backend.Backend, cty.V if validateDiags.HasErrors() { return nil, cty.NilVal, diags } - configVal = newVal - configureDiags := b.Configure(configVal) + configureDiags := b.Configure(newVal) diags = diags.Append(configureDiags.InConfigBody(c.Config)) return b, configVal, diags @@ -1082,9 +1079,8 @@ func (m *Meta) backendInitFromSaved(s *terraform.BackendState) (backend.Backend, if validateDiags.HasErrors() { return nil, diags } - configVal = newVal - configureDiags := b.Configure(configVal) + configureDiags := b.Configure(newVal) diags = diags.Append(configureDiags) return b, diags diff --git a/command/meta_backend_migrate.go b/command/meta_backend_migrate.go index 8d020f90a..9227844a1 100644 --- a/command/meta_backend_migrate.go +++ b/command/meta_backend_migrate.go @@ -98,7 +98,6 @@ func (m *Meta) backendMigrateState(opts *backendMigrateOpts) error { // Multi-state to multi-state. We merge the states together (migrating // each from the source to the destination one by one). case !oneSingle && !twoSingle: - fmt.Printf("STATES: %q\n", oneStates) // If the source only has one state and it is the default, // treat it as if it doesn't support multi-state. if len(oneStates) == 1 && oneStates[0] == backend.DefaultStateName {