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  }