command/init: return an error with invalid -backend-config files (#25411)
* command/init: return an error with invalid -backend-config files The -backend-config flag expects a set of key-value pairs or a file containing key-value pairs. If the file instead contains a full backend configuration block, it was silently ignored. This commit adds a check for blocks in the file and returns an error if they are encountered. Fixes #24845 * emphasize backend configuration file in docs
This commit is contained in:
parent
0b3c0f64c2
commit
df244b87c2
|
@ -803,6 +803,18 @@ func (c *InitCommand) backendConfigOverrideBody(flags rawFlags, schema *configsc
|
|||
// The value is interpreted as a filename.
|
||||
newBody, fileDiags := c.loadHCLFile(item.Value)
|
||||
diags = diags.Append(fileDiags)
|
||||
// Verify that the file contains only key-values pairs, and not a
|
||||
// full backend config block. JustAttributes() will return an error
|
||||
// if blocks are found
|
||||
_, attrDiags := newBody.JustAttributes()
|
||||
if attrDiags.HasErrors() {
|
||||
diags = diags.Append(tfdiags.Sourceless(
|
||||
tfdiags.Error,
|
||||
"Invalid backend configuration file",
|
||||
fmt.Sprintf("The backend configuration file %q given on the command line must contain key-value pairs only, and not configuration blocks.", item.Value),
|
||||
))
|
||||
continue
|
||||
}
|
||||
flushVals() // deal with any accumulated individual values first
|
||||
mergeBody(newBody)
|
||||
} else {
|
||||
|
|
|
@ -337,24 +337,43 @@ func TestInit_backendConfigFile(t *testing.T) {
|
|||
defer os.RemoveAll(td)
|
||||
defer testChdir(t, td)()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
c := &InitCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
t.Run("good-config-file", func(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &InitCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
args := []string{"-backend-config", "input.config"}
|
||||
if code := c.Run(args); code != 0 {
|
||||
t.Fatalf("bad: \n%s", ui.ErrorWriter.String())
|
||||
}
|
||||
|
||||
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 := testDataStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
|
||||
if got, want := normalizeJSON(t, state.Backend.ConfigRaw), `{"path":"hello","workspace_dir":null}`; got != want {
|
||||
t.Errorf("wrong config\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
})
|
||||
|
||||
// Read our saved backend config and verify we have our settings
|
||||
state := testDataStateRead(t, filepath.Join(DefaultDataDir, DefaultStateFilename))
|
||||
if got, want := normalizeJSON(t, state.Backend.ConfigRaw), `{"path":"hello","workspace_dir":null}`; got != want {
|
||||
t.Errorf("wrong config\ngot: %s\nwant: %s", got, want)
|
||||
}
|
||||
// the backend config file must be a set of key-value pairs and not a full backend {} block
|
||||
t.Run("invalid-config-file", func(t *testing.T) {
|
||||
ui := new(cli.MockUi)
|
||||
c := &InitCommand{
|
||||
Meta: Meta{
|
||||
testingOverrides: metaOverridesForProvider(testProvider()),
|
||||
Ui: ui,
|
||||
},
|
||||
}
|
||||
args := []string{"-backend-config", "backend.config"}
|
||||
if code := c.Run(args); code != 1 {
|
||||
t.Fatalf("expected error, got success\n")
|
||||
}
|
||||
if !strings.Contains(ui.ErrorWriter.String(), "Invalid backend configuration file") {
|
||||
t.Fatalf("wrong error: %s", ui.ErrorWriter)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestInit_backendConfigFilePowershellConfusion(t *testing.T) {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// the -backend-config flag on init cannot be used to point to a "full" backend
|
||||
// block, only key-value pairs (like terraform.tfvars)
|
||||
terraform {
|
||||
backend "local" {
|
||||
path = "hello"
|
||||
}
|
||||
}
|
|
@ -63,12 +63,12 @@ There are several ways to supply the remaining arguments:
|
|||
values, unless interactive input is disabled. Terraform will not prompt for
|
||||
optional values.
|
||||
|
||||
* **File**: A configuration file may be specified via the `init` command line.
|
||||
To specify a file, use the `-backend-config=PATH` option when running
|
||||
`terraform init`. If the file contains secrets it may be kept in
|
||||
a secure data store, such as
|
||||
[Vault](https://www.vaultproject.io/), in which case it must be downloaded
|
||||
to the local disk before running Terraform.
|
||||
* **File**: A [backend configuration file](#backend-configuration-file) may be specified via the
|
||||
`init` command line. To specify a file, use the `-backend-config=PATH`
|
||||
option when running `terraform init`. If the file contains secrets it may be
|
||||
kept in a secure data store, such as [Vault](https://www.vaultproject.io/),
|
||||
in which case it must be downloaded to the local disk before running
|
||||
Terraform.
|
||||
|
||||
* **Command-line key/value pairs**: Key/value pairs can be specified via the
|
||||
`init` command line. Note that many shells retain command-line flags in a
|
||||
|
@ -96,6 +96,7 @@ terraform {
|
|||
}
|
||||
```
|
||||
|
||||
## Backend Configuration File
|
||||
A backend configuration file has the contents of the `backend` block as
|
||||
top-level attributes, without the need to wrap it in another `terraform`
|
||||
or `backend` block:
|
||||
|
|
Loading…
Reference in New Issue