From 464cb2f9611e902953d294f66884da40152490ad Mon Sep 17 00:00:00 2001 From: Anubhav Mishra Date: Mon, 25 Sep 2017 11:47:02 -0700 Subject: [PATCH] Extra arguments environment variables (#150) * first draft of the populate function * Now extra arguments can use environment variables. Fixes #146 * now using environment variables while executing terraform commands for variables subsitution * fix order of terraform command arguments * Adding single quote around terraform command * please work this time :) * fix order for the quote * fix order for the quote * Adding single quote around terraform command * now creating terraform command string to address bash interpolation * now using 'sh' instead of 'bash' to execute terraform command and added docs about v and env after review --- server/apply_executor.go | 2 +- server/plan_executor.go | 4 ++-- terraform/terraform_client.go | 31 +++++++++++++++++++++++++------ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/server/apply_executor.go b/server/apply_executor.go index 7bde42e79d..b83c42529c 100644 --- a/server/apply_executor.go +++ b/server/apply_executor.go @@ -146,7 +146,7 @@ func (a *ApplyExecutor) apply(ctx *CommandContext, repoDir string, plan models.P } tfApplyCmd := append(append([]string{"apply", "-no-color", plan.LocalPath}, applyExtraArgs...), ctx.Command.Flags...) - output, err := a.terraform.RunCommandWithVersion(ctx.Log, absolutePath, tfApplyCmd, terraformVersion) + output, err := a.terraform.RunCommandWithVersion(ctx.Log, absolutePath, tfApplyCmd, terraformVersion, tfEnv) if err != nil { return ProjectResult{Error: fmt.Errorf("%s\n%s", err.Error(), output)} } diff --git a/server/plan_executor.go b/server/plan_executor.go index b5013170cc..56fe4e1057 100644 --- a/server/plan_executor.go +++ b/server/plan_executor.go @@ -144,7 +144,7 @@ func (p *PlanExecutor) plan(ctx *CommandContext, repoDir string, project models. } else { ctx.Log.Info("determined that we are running terraform with version < 0.9.0. Running version %s", terraformVersion) terraformGetCmd := append([]string{"get", "-no-color"}, config.GetExtraArguments("get")...) - _, err := p.terraform.RunCommandWithVersion(ctx.Log, absolutePath, terraformGetCmd, terraformVersion) + _, err := p.terraform.RunCommandWithVersion(ctx.Log, absolutePath, terraformGetCmd, terraformVersion, tfEnv) if err != nil { return ProjectResult{Error: err} } @@ -168,7 +168,7 @@ func (p *PlanExecutor) plan(ctx *CommandContext, repoDir string, project models. if _, err := os.Stat(filepath.Join(repoDir, project.Path, tfEnvFileName)); err == nil { tfPlanCmd = append(tfPlanCmd, "-var-file", tfEnvFileName) } - output, err := p.terraform.RunCommandWithVersion(ctx.Log, filepath.Join(repoDir, project.Path), tfPlanCmd, terraformVersion) + output, err := p.terraform.RunCommandWithVersion(ctx.Log, filepath.Join(repoDir, project.Path), tfPlanCmd, terraformVersion, tfEnv) if err != nil { // plan failed so unlock the state if _, err := p.lockingClient.Unlock(lockAttempt.LockKey); err != nil { diff --git a/terraform/terraform_client.go b/terraform/terraform_client.go index beade0226e..d5c40862f4 100644 --- a/terraform/terraform_client.go +++ b/terraform/terraform_client.go @@ -3,6 +3,7 @@ package terraform import ( "fmt" + "os" "os/exec" "regexp" @@ -51,15 +52,33 @@ func (c *Client) Version() *version.Version { } // RunCommandWithVersion executes the provided version of terraform with -// the provided args in path. -func (c *Client) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, v *version.Version) (string, error) { +// the provided args in path. The variable "v" is the version of terraform executable to use and the variable "env" is the +// environment specified by the user commenting "atlantis plan/apply {env}" which is set to "default" by default. +func (c *Client) RunCommandWithVersion(log *logging.SimpleLogger, path string, args []string, v *version.Version, env string) (string, error) { tfExecutable := "terraform" // if version is the same as the default, don't need to prepend the version name to the executable if !v.Equal(c.defaultVersion) { tfExecutable = fmt.Sprintf("%s%s", tfExecutable, v.String()) } - terraformCmd := exec.Command(tfExecutable, args...) + + // set environment variables + // this is to support scripts to use the ENVIRONMENT, ATLANTIS_TERRAFORM_VERSION + // and WORKSPACE variables in their scripts + // append current process's environment variables + // this is to prevent the $PATH variable being removed from the environment + envVars := []string{ + fmt.Sprintf("ENVIRONMENT=%s", env), + fmt.Sprintf("ATLANTIS_TERRAFORM_VERSION=%s", v.String()), + fmt.Sprintf("WORKSPACE=%s", path), + } + envVars = append(envVars, os.Environ()...) + + // append terraform executable name with args + tfCmd := fmt.Sprintf("%s %s", tfExecutable, strings.Join(args, " ")) + + terraformCmd := exec.Command("sh", "-c", tfCmd) terraformCmd.Dir = path + terraformCmd.Env = envVars out, err := terraformCmd.CombinedOutput() commandStr := strings.Join(terraformCmd.Args, " ") if err != nil { @@ -77,19 +96,19 @@ func (c *Client) RunCommandWithVersion(log *logging.SimpleLogger, path string, a func (c *Client) RunInitAndEnv(log *logging.SimpleLogger, path string, env string, extraInitArgs []string, version *version.Version) ([]string, error) { var outputs []string // run terraform init - output, err := c.RunCommandWithVersion(log, path, append([]string{"init", "-no-color"}, extraInitArgs...), version) + output, err := c.RunCommandWithVersion(log, path, append([]string{"init", "-no-color"}, extraInitArgs...), version, env) outputs = append(outputs, output) if err != nil { return outputs, err } // run terraform env new and select - output, err = c.RunCommandWithVersion(log, path, []string{"env", "select", "-no-color", env}, version) + output, err = c.RunCommandWithVersion(log, path, []string{"env", "select", "-no-color", env}, version, env) outputs = append(outputs, output) if err != nil { // if terraform env select fails we will run terraform env new // to create a new environment - output, err = c.RunCommandWithVersion(log, path, []string{"env", "new", "-no-color", env}, version) + output, err = c.RunCommandWithVersion(log, path, []string{"env", "new", "-no-color", env}, version, env) if err != nil { return outputs, err }