github.com/mponton/terratest@v0.44.0/modules/terraform/cmd.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 6 "github.com/mponton/terratest/modules/collections" 7 "github.com/mponton/terratest/modules/retry" 8 "github.com/mponton/terratest/modules/shell" 9 "github.com/mponton/terratest/modules/testing" 10 ) 11 12 func generateCommand(options *Options, args ...string) shell.Command { 13 cmd := shell.Command{ 14 Command: options.TerraformBinary, 15 Args: args, 16 WorkingDir: options.TerraformDir, 17 Env: options.EnvVars, 18 Logger: options.Logger, 19 } 20 return cmd 21 } 22 23 var commandsWithParallelism = []string{ 24 "plan", 25 "apply", 26 "destroy", 27 "plan-all", 28 "run-all", 29 "apply-all", 30 "destroy-all", 31 } 32 33 // GetCommonOptions extracts commons terraform options 34 func GetCommonOptions(options *Options, args ...string) (*Options, []string) { 35 if options.TerraformBinary == "" { 36 options.TerraformBinary = "terraform" 37 } 38 39 if options.TerraformBinary == "terragrunt" { 40 args = append(args, "--terragrunt-non-interactive") 41 } 42 43 if options.Parallelism > 0 && len(args) > 0 && collections.ListContains(commandsWithParallelism, args[0]) { 44 args = append(args, fmt.Sprintf("--parallelism=%d", options.Parallelism)) 45 } 46 47 // if SshAgent is provided, override the local SSH agent with the socket of our in-process agent 48 if options.SshAgent != nil { 49 // Initialize EnvVars, if it hasn't been set yet 50 if options.EnvVars == nil { 51 options.EnvVars = map[string]string{} 52 } 53 options.EnvVars["SSH_AUTH_SOCK"] = options.SshAgent.SocketFile() 54 } 55 return options, args 56 } 57 58 // RunTerraformCommand runs terraform with the given arguments and options and return stdout/stderr. 59 func RunTerraformCommand(t testing.TestingT, additionalOptions *Options, args ...string) string { 60 out, err := RunTerraformCommandE(t, additionalOptions, args...) 61 if err != nil { 62 t.Fatal(err) 63 } 64 return out 65 } 66 67 // RunTerraformCommandE runs terraform with the given arguments and options and return stdout/stderr. 68 func RunTerraformCommandE(t testing.TestingT, additionalOptions *Options, additionalArgs ...string) (string, error) { 69 options, args := GetCommonOptions(additionalOptions, additionalArgs...) 70 71 cmd := generateCommand(options, args...) 72 description := fmt.Sprintf("%s %v", options.TerraformBinary, args) 73 return retry.DoWithRetryableErrorsE(t, description, options.RetryableTerraformErrors, options.MaxRetries, options.TimeBetweenRetries, func() (string, error) { 74 return shell.RunCommandAndGetOutputE(t, cmd) 75 }) 76 } 77 78 // RunTerraformCommandAndGetStdoutE runs terraform with the given arguments and options and returns solely its stdout 79 // (but not stderr). 80 func RunTerraformCommandAndGetStdoutE(t testing.TestingT, additionalOptions *Options, additionalArgs ...string) (string, error) { 81 options, args := GetCommonOptions(additionalOptions, additionalArgs...) 82 83 cmd := generateCommand(options, args...) 84 description := fmt.Sprintf("%s %v", options.TerraformBinary, args) 85 return retry.DoWithRetryableErrorsE(t, description, options.RetryableTerraformErrors, options.MaxRetries, options.TimeBetweenRetries, func() (string, error) { 86 return shell.RunCommandAndGetStdOutE(t, cmd) 87 }) 88 } 89 90 // GetExitCodeForTerraformCommand runs terraform with the given arguments and options and returns exit code 91 func GetExitCodeForTerraformCommand(t testing.TestingT, additionalOptions *Options, args ...string) int { 92 exitCode, err := GetExitCodeForTerraformCommandE(t, additionalOptions, args...) 93 if err != nil { 94 t.Fatal(err) 95 } 96 return exitCode 97 } 98 99 // GetExitCodeForTerraformCommandE runs terraform with the given arguments and options and returns exit code 100 func GetExitCodeForTerraformCommandE(t testing.TestingT, additionalOptions *Options, additionalArgs ...string) (int, error) { 101 options, args := GetCommonOptions(additionalOptions, additionalArgs...) 102 103 additionalOptions.Logger.Logf(t, "Running %s with args %v", options.TerraformBinary, args) 104 cmd := generateCommand(options, args...) 105 _, err := shell.RunCommandAndGetOutputE(t, cmd) 106 if err == nil { 107 return DefaultSuccessExitCode, nil 108 } 109 exitCode, getExitCodeErr := shell.GetExitCodeForRunCommandError(err) 110 if getExitCodeErr == nil { 111 return exitCode, nil 112 } 113 return DefaultErrorExitCode, getExitCodeErr 114 }