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

Adding suport for -var-file and -target argument #201

Merged
merged 18 commits into from Feb 17, 2019
Merged
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
41 changes: 41 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion examples/terraform-basic-example/main.tf
Expand Up @@ -5,4 +5,17 @@

data "template_file" "example" {
template = "${var.example}"
}
}

data "template_file" "example2" {
template = "${var.example2}"
}
resource "local_file" "example" {
content = "${data.template_file.example.rendered} + ${data.template_file.example2.rendered}"
filename = "example.txt"
}

resource "local_file" "example2" {
content = "${data.template_file.example2.rendered}"
filename = "example2.txt"
}
6 changes: 5 additions & 1 deletion examples/terraform-basic-example/outputs.tf
@@ -1,3 +1,7 @@
output "example" {
value = "${data.template_file.example.rendered}"
}
}

output "example2" {
value = "${data.template_file.example2.rendered}"
}
1 change: 1 addition & 0 deletions examples/terraform-basic-example/varfile.tfvars
@@ -0,0 +1 @@
example2 = "test"
7 changes: 6 additions & 1 deletion examples/terraform-basic-example/variables.tf
Expand Up @@ -20,4 +20,9 @@
variable "example" {
description = "Example variable"
default = "example"
}
}

variable "example2" {
description = "Example variable 2"
default = ""
}
2 changes: 1 addition & 1 deletion modules/terraform/apply.go
Expand Up @@ -43,5 +43,5 @@ func Apply(t *testing.T, options *Options) string {
// ApplyE runs terraform apply with the given options and return stdout/stderr. Note that this method does NOT call destroy and
// assumes the caller is responsible for cleaning up any resources created by running apply.
func ApplyE(t *testing.T, options *Options) (string, error) {
return RunTerraformCommandE(t, options, FormatArgs(options.Vars, "apply", "-input=false", "-lock=false", "-auto-approve")...)
return RunTerraformCommandE(t, options, FormatArgs(options, "apply", "-input=false", "-lock=false", "-auto-approve")...)
}
1 change: 0 additions & 1 deletion modules/terraform/cmd.go
Expand Up @@ -16,7 +16,6 @@ func GetCommonOptions(options *Options, args ...string) (*Options, []string) {
if options.NoColor && !collections.ListContains(args, "-no-color") {
args = append(args, "-no-color")
}

// if SshAgent is provided, override the local SSH agent with the socket of our in-process agent
if options.SshAgent != nil {
// Initialize EnvVars, if it hasn't been set yet
Expand Down
2 changes: 1 addition & 1 deletion modules/terraform/destroy.go
Expand Up @@ -15,5 +15,5 @@ func Destroy(t *testing.T, options *Options) string {

// DestroyE runs terraform destroy with the given options and return stdout/stderr.
func DestroyE(t *testing.T, options *Options) (string, error) {
return RunTerraformCommandE(t, options, FormatArgs(options.Vars, "destroy", "-auto-approve", "-input=false", "-lock=false")...)
return RunTerraformCommandE(t, options, FormatArgs(options, "destroy", "-auto-approve", "-input=false", "-lock=false")...)
}
20 changes: 17 additions & 3 deletions modules/terraform/format.go
Expand Up @@ -8,9 +8,13 @@ import (

// FormatArgs converts the inputs to a format palatable to terraform. This includes converting the given vars to the
// format the Terraform CLI expects (-var key=value).
func FormatArgs(customVars map[string]interface{}, args ...string) []string {
varsAsArgs := FormatTerraformVarsAsArgs(customVars)
return append(args, varsAsArgs...)
func FormatArgs(options *Options, args ...string) []string {
var terraformArgs []string
terraformArgs = append(terraformArgs, args...)
terraformArgs = append(terraformArgs, FormatTerraformVarsAsArgs(options.Vars)...)
terraformArgs = append(terraformArgs, FormatTerraformArgs("-var-file", options.VarFiles)...)
terraformArgs = append(terraformArgs, FormatTerraformArgs("-target", options.Targets)...)
return terraformArgs
}

// FormatTerraformVarsAsArgs formats the given variables as command-line args for Terraform (e.g. of the format
Expand All @@ -19,6 +23,16 @@ func FormatTerraformVarsAsArgs(vars map[string]interface{}) []string {
return formatTerraformArgs(vars, "-var")
}

// FormatTerraformArgs will format multiple args with the arg name (e.g. "-var-file", []string{"foo.tfvars", "bar.tfvars"})
// returns "-var-file foo.tfvars -var-file bar.tfvars"
func FormatTerraformArgs(argName string, args []string) []string {
argsList := []string{}
for _, argValue := range args {
argsList = append(argsList, argName, argValue)
}
return argsList
}

// FormatTerraformBackendConfigAsArgs formats the given variables as backend config args for Terraform (e.g. of the
// format -backend-config key=value).
func FormatTerraformBackendConfigAsArgs(vars map[string]interface{}) []string {
Expand Down
2 changes: 2 additions & 0 deletions modules/terraform/options.go
Expand Up @@ -10,6 +10,8 @@ import (
type Options struct {
TerraformDir string // The path to the folder where the Terraform code is defined.
Vars map[string]interface{} // The vars to pass to Terraform commands using the -var option.
VarFiles []string // The var file paths to pass to Terraform commands using -var-file option.
Targets []string // The target resources to pass to the terraform command with -target
EnvVars map[string]string // Environment variables to set when running Terraform
BackendConfig map[string]interface{} // The vars to pass to the terraform init command for extra configuration for the backend
RetryableTerraformErrors map[string]string // If Terraform apply fails with one of these (transient) errors, retry. The keys are text to look for in the error and the message is what to display to a user if that error is found.
Expand Down
2 changes: 1 addition & 1 deletion modules/terraform/plan.go
Expand Up @@ -33,5 +33,5 @@ func PlanExitCode(t *testing.T, options *Options) int {

// PlanExitCodeE runs terraform apply with the given options and returns the detailed exitcode.
func PlanExitCodeE(t *testing.T, options *Options) (int, error) {
return GetExitCodeForTerraformCommandE(t, options, FormatArgs(options.Vars, "plan", "-input=false", "-lock=true", "-detailed-exitcode")...)
return GetExitCodeForTerraformCommandE(t, options, FormatArgs(options, "plan", "-input=false", "-lock=true", "-detailed-exitcode")...)
}
33 changes: 32 additions & 1 deletion test/terraform_basic_example_test.go
Expand Up @@ -10,12 +10,13 @@ import (
// An example of how to test the simple Terraform module in examples/terraform-basic-example using Terratest.
func TestTerraformBasicExample(t *testing.T) {
t.Parallel()
terraformDir := "../examples/terraform-basic-example"

expectedText := "foo"

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: "../examples/terraform-basic-example",
TerraformDir: terraformDir,

// Variables to pass to our Terraform code using -var options
Vars: map[string]interface{}{
Expand All @@ -37,3 +38,33 @@ func TestTerraformBasicExample(t *testing.T) {
// Verify we're getting back the variable we expect
assert.Equal(t, expectedText, actualText)
}

// An example of using -var-file argument in a test
func TestTerraformVarFilesExample(t *testing.T) {
t.Parallel()
terraformDir := "../examples/terraform-basic-example"

expectedText := "test"

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: terraformDir,

// Use the var files
VarFiles: []string{"varfile.tfvars"},

NoColor: true,
}

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

// This will run `terraform init` and `terraform apply` and fail the test if there are any errors
terraform.InitAndApply(t, terraformOptions)

// Test for the variable which comes from the var file
actualText := terraform.Output(t, terraformOptions, "example2")

// Verify we're getting the expected value from the file
assert.Equal(t, expectedText, actualText)
}