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