Skip to content

Commit

Permalink
fix: add additional flags to init command
Browse files Browse the repository at this point in the history
ensure existing properties specifically called out are "protected"

addressess gruntwork-io#318
  • Loading branch information
dnitsch committed Mar 6, 2023
1 parent 09301eb commit 8533008
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 0 deletions.
15 changes: 15 additions & 0 deletions modules/terraform/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package terraform

import (
"fmt"
"strings"

"github.com/gruntwork-io/terratest/modules/testing"
)
Expand Down Expand Up @@ -30,5 +31,19 @@ func InitE(t testing.TestingT, options *Options) (string, error) {

args = append(args, FormatTerraformBackendConfigAsArgs(options.BackendConfig)...)
args = append(args, FormatTerraformPluginDirAsArgs(options.PluginDir)...)
// Down to the user to supply to correct flags
if len(options.AdditionalInitFlags) > 0 {

for _, v := range options.AdditionalInitFlags {
if strings.HasPrefix(v, "-upgrade") ||
strings.HasPrefix(v, "-reconfigure") ||
strings.HasPrefix(v, "-migrate-state") ||
strings.HasPrefix(v, "-force-copy") {
continue
}
args = append(args, v)
}
}

return RunTerraformCommandE(t, options, args...)
}
145 changes: 145 additions & 0 deletions modules/terraform/init_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package terraform

import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"testing"

"github.com/gruntwork-io/terratest/modules/files"
"github.com/gruntwork-io/terratest/modules/logger"
ttest "github.com/gruntwork-io/terratest/modules/testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -132,3 +137,143 @@ func TestInitBackendMigration(t *testing.T) {
_, err = InitE(t, options)
assert.NoError(t, err, "Backend initialization with changed configuration should success with -migrate-state option")
}

type testLog struct {
w io.Writer
}

func (l testLog) Logf(t ttest.TestingT, format string, args ...interface{}) {
fmt.Fprintf(l.w, format, args...)
}

func TestInitAdditionalFlags(t *testing.T) {
t.Parallel()

ttests := map[string]struct {
// returns logged out buffer, opts, expect string, cleanup
setup func(t *testing.T) (*bytes.Buffer, *Options, string, func())
}{
"backend set to false": {
func(t *testing.T) (*bytes.Buffer, *Options, string, func()) {
b := &bytes.Buffer{}
l := testLog{b}
stateDirectory := t.TempDir()
testFolder, err := files.CopyTerraformFolderToTemp("../../test/fixtures/terraform-backend", "")
require.NoError(t, err)
backendPath := filepath.Join(stateDirectory, "backend.tfstate")

return b,
&Options{
Logger: logger.New(l),
TerraformDir: testFolder,
Reconfigure: true,
BackendConfig: map[string]any{
"path": backendPath,
},
AdditionalInitFlags: []string{"-backend=false"},
},
fmt.Sprintf("[init -upgrade=false -reconfigure -backend-config=path=%s -backend=false]", backendPath),
func() {
os.RemoveAll(testFolder)
}
},
},
"backend set to true": {
func(t *testing.T) (*bytes.Buffer, *Options, string, func()) {
b := &bytes.Buffer{}
l := testLog{b}
stateDirectory := t.TempDir()
testFolder, err := files.CopyTerraformFolderToTemp("../../test/fixtures/terraform-backend", "")
require.NoError(t, err)
backendPath := filepath.Join(stateDirectory, "backend.tfstate")

return b, &Options{
Logger: logger.New(l),
TerraformDir: testFolder,
Reconfigure: true,
BackendConfig: map[string]any{
"path": backendPath,
},
AdditionalInitFlags: []string{"-backend=true"},
},
fmt.Sprintf("[init -upgrade=false -reconfigure -backend-config=path=%s -backend=true]", backendPath),
func() {
os.RemoveAll(testFolder)
}
},
},
"backend not set via additional args": {
func(t *testing.T) (*bytes.Buffer, *Options, string, func()) {
b := &bytes.Buffer{}
l := testLog{b}
stateDirectory := t.TempDir()
testFolder, err := files.CopyTerraformFolderToTemp("../../test/fixtures/terraform-backend", "")
require.NoError(t, err)
backendPath := filepath.Join(stateDirectory, "backend.tfstate")

return b, &Options{
Logger: logger.New(l),
TerraformDir: testFolder,
Reconfigure: true,
BackendConfig: map[string]any{
"path": backendPath,
},
AdditionalInitFlags: []string{},
},
fmt.Sprintf("[init -upgrade=false -reconfigure -backend-config=path=%s]", backendPath),
func() {
os.RemoveAll(testFolder)
}
},
},
// should ignore the
"backend set to false and protected flags re-specified": {
setup: func(t *testing.T) (*bytes.Buffer, *Options, string, func()) {
b := &bytes.Buffer{}
l := testLog{b}
stateDirectory := t.TempDir()
testFolder, err := files.CopyTerraformFolderToTemp("../../test/fixtures/terraform-backend", "")
require.NoError(t, err)
backendPath := filepath.Join(stateDirectory, "backend.tfstate")
return b,
&Options{
Logger: logger.New(l),
TerraformDir: testFolder,
Reconfigure: false,
MigrateState: false,
BackendConfig: map[string]any{
"path": backendPath,
},
AdditionalInitFlags: []string{"-backend=false", "-reconfigure", "-migrate-state"},
},
fmt.Sprintf("[init -upgrade=false -backend-config=path=%s -backend=false]", backendPath),
func() {
os.RemoveAll(testFolder)
}
},
},
}
for name, tt := range ttests {
t.Run(name, func(t *testing.T) {

b, options, expect, cleanUp := tt.setup(t)
defer cleanUp()
_, _ = InitE(t, options)
assert.Contains(t, b.String(), expect)

if expect == "-backend=true" {
if statePath, ok := options.BackendConfig["path"]; ok {
ls, _ := os.ReadDir(fmt.Sprintf("%s", statePath))
for idx, v := range ls {
if v.Name() == "backend.tfstate" {
return
}
if idx == len(ls) {
t.Errorf("failed to find backend state file when it should have been created under: %s", statePath)
}
}
}
}
})
}
}
2 changes: 2 additions & 0 deletions modules/terraform/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ type Options struct {
PlanFilePath string // The path to output a plan file to (for the plan command) or read one from (for the apply command)
PluginDir string // The path of downloaded plugins to pass to the terraform init command (-plugin-dir)
SetVarsAfterVarFiles bool // Pass -var options after -var-file options to Terraform commands
AdditionalInitFlags []string // additional flags to pass to init command - e.g. `-backend=false`. complete list of options [here](https://developer.hashicorp.com/terraform/cli/commands/init)
// AdditionalApplyDestroylags []string // additional flags to pass to apply/destroy command
}

// Clone makes a deep copy of most fields on the Options object and returns it.
Expand Down

0 comments on commit 8533008

Please sign in to comment.