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.
This commit is contained in:
James Bardin 2019-05-24 14:51:18 -04:00
parent ee9a618369
commit c017149b31
3 changed files with 50 additions and 9 deletions

View File

@ -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) { func TestInit_targetSubdir(t *testing.T) {
// Create a temporary working directory that is empty // Create a temporary working directory that is empty
td := tempDir(t) td := tempDir(t)

View File

@ -185,9 +185,8 @@ func (m *Meta) BackendForPlan(settings plans.Backend) (backend.Enhanced, tfdiags
if validateDiags.HasErrors() { if validateDiags.HasErrors() {
return nil, diags return nil, diags
} }
configVal = newVal
configureDiags := b.Configure(configVal) configureDiags := b.Configure(newVal)
diags = diags.Append(configureDiags) diags = diags.Append(configureDiags)
// If the backend supports CLI initialization, do it. // 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() { if validDiags.HasErrors() {
return nil, diags return nil, diags
} }
configVal = newVal
configDiags := b.Configure(configVal) configDiags := b.Configure(newVal)
diags = diags.Append(configDiags) diags = diags.Append(configDiags)
if configDiags.HasErrors() { if configDiags.HasErrors() {
return nil, diags return nil, diags
@ -1051,9 +1049,8 @@ func (m *Meta) backendInitFromConfig(c *configs.Backend) (backend.Backend, cty.V
if validateDiags.HasErrors() { if validateDiags.HasErrors() {
return nil, cty.NilVal, diags return nil, cty.NilVal, diags
} }
configVal = newVal
configureDiags := b.Configure(configVal) configureDiags := b.Configure(newVal)
diags = diags.Append(configureDiags.InConfigBody(c.Config)) diags = diags.Append(configureDiags.InConfigBody(c.Config))
return b, configVal, diags return b, configVal, diags
@ -1082,9 +1079,8 @@ func (m *Meta) backendInitFromSaved(s *terraform.BackendState) (backend.Backend,
if validateDiags.HasErrors() { if validateDiags.HasErrors() {
return nil, diags return nil, diags
} }
configVal = newVal
configureDiags := b.Configure(configVal) configureDiags := b.Configure(newVal)
diags = diags.Append(configureDiags) diags = diags.Append(configureDiags)
return b, diags return b, diags

View File

@ -98,7 +98,6 @@ func (m *Meta) backendMigrateState(opts *backendMigrateOpts) error {
// Multi-state to multi-state. We merge the states together (migrating // Multi-state to multi-state. We merge the states together (migrating
// each from the source to the destination one by one). // each from the source to the destination one by one).
case !oneSingle && !twoSingle: case !oneSingle && !twoSingle:
fmt.Printf("STATES: %q\n", oneStates)
// If the source only has one state and it is the default, // If the source only has one state and it is the default,
// treat it as if it doesn't support multi-state. // treat it as if it doesn't support multi-state.
if len(oneStates) == 1 && oneStates[0] == backend.DefaultStateName { if len(oneStates) == 1 && oneStates[0] == backend.DefaultStateName {