Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose additional args to init command #1259

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 17 additions & 0 deletions modules/terraform/init.go
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,21 @@ 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
// AdditionalInitFlags should not overwrite previously set
// flags via Options public properties
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...)
}
132 changes: 132 additions & 0 deletions modules/terraform/init_test.go
@@ -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,130 @@ 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", "be-set-to-false")
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", "be-set-to-true")
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", "not-set-via-args")
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", "be-no-specified")
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()
_, err := InitE(t, options)
assert.Contains(t, b.String(), expect)
assert.NoError(t, err)
})
}
}
2 changes: 2 additions & 0 deletions modules/terraform/options.go
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AdditionalApplyDestroylags is required? - looks like it is commented and not referenced

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes correct ... can be deleted.

}

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