Repository: diggerhq/digger
Pull request #209 (2023-05-05 13:14:54)

feat: add env variable support


Patch:
diff --git a/action.yml b/action.yml
index 0fa50375..2046698d 100644
--- a/action.yml
+++ b/action.yml
@@ -65,16 +65,6 @@ outputs:
 runs:
   using: composite
   steps:
-    - name: Validate General Input Configuration
-      run: |
-        if [[ "${{ inputs.setup-aws }}" == "false" && "${{ inputs.setup-google-cloud }}" == "false" ]]; then
-          echo "Either 'setup-aws' or 'setup-google-cloud' input must be set to 'true'"
-        else
-          exit 0
-        fi
-        exit 1
-      shell: bash
-
     - name: Validate Input Configuration for Google
       run: |
         if [[ -z ${{ toJSON(inputs.google-auth-credentials) }} && -z "${{ inputs.google-workload-identity-provider }}" ]]; then
diff --git a/go.mod b/go.mod
index 564638f9..1592e107 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,7 @@ require (
 	cloud.google.com/go/storage v1.30.1
 	github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0
 	github.com/Azure/azure-sdk-for-go/sdk/data/aztables v1.0.1
-	github.com/aws/aws-sdk-go v1.44.255
+	github.com/aws/aws-sdk-go v1.44.257
 	github.com/bmatcuk/doublestar/v4 v4.6.0
 	github.com/google/go-github/v51 v51.0.0
 	github.com/google/go-github/v52 v52.0.0
diff --git a/go.sum b/go.sum
index 4e27f06f..8685856b 100644
--- a/go.sum
+++ b/go.sum
@@ -35,6 +35,8 @@ github.com/aws/aws-sdk-go v1.44.254 h1:8baW4yal2xGiM/Wm5/ZU10drS8sd+BVjMjPFjJx2o
 github.com/aws/aws-sdk-go v1.44.254/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 github.com/aws/aws-sdk-go v1.44.255 h1:tOd7OP5V6BeHhANksc7CFB/ILS2mHj3kRhTfZKFnsS0=
 github.com/aws/aws-sdk-go v1.44.255/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
+github.com/aws/aws-sdk-go v1.44.257 h1:HwelXYZZ8c34uFFhgVw3ybu2gB5fkk8KLj2idTvzZb8=
+github.com/aws/aws-sdk-go v1.44.257/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
 github.com/bmatcuk/doublestar/v4 v4.6.0 h1:HTuxyug8GyFbRkrffIpzNCSK4luc0TY3wzXvzIZhEXc=
 github.com/bmatcuk/doublestar/v4 v4.6.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
 github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
diff --git a/pkg/configuration/digger_config.go b/pkg/configuration/digger_config.go
index fa54583b..1bd608cf 100644
--- a/pkg/configuration/digger_config.go
+++ b/pkg/configuration/digger_config.go
@@ -25,6 +25,12 @@ type DiggerConfigYaml struct {
 	GenerateProjectsConfig *GenerateProjectsConfig `yaml:"generate_projects"`
 }
 
+type EnvVarConfig struct {
+	Name      string `yaml:"name"`
+	ValueFrom string `yaml:"value_from"`
+	Value     string `yaml:"value"`
+}
+
 type DiggerConfig struct {
 	Projects         []Project
 	AutoMerge        bool
@@ -50,11 +56,17 @@ type Stage struct {
 }
 
 type Workflow struct {
+	EnvVars       EnvVars                `yaml:"env_vars"`
 	Plan          *Stage                 `yaml:"plan,omitempty"`
 	Apply         *Stage                 `yaml:"apply,omitempty"`
 	Configuration *WorkflowConfiguration `yaml:"workflow_configuration"`
 }
 
+type EnvVars struct {
+	State    []EnvVarConfig `yaml:"state"`
+	Commands []EnvVarConfig `yaml:"commands"`
+}
+
 type DirWalker interface {
 	GetDirs(workingDir string) ([]string, error)
 }
@@ -125,6 +137,10 @@ func (w *Workflow) UnmarshalYAML(unmarshal func(interface{}) error) error {
 				},
 			},
 		},
+		EnvVars: EnvVars{
+			State:    []EnvVarConfig{},
+			Commands: []EnvVarConfig{},
+		},
 	}
 	if err := unmarshal(&raw); err != nil {
 		return err
diff --git a/pkg/digger/digger.go b/pkg/digger/digger.go
index cee1b604..c14bb7cf 100644
--- a/pkg/digger/digger.go
+++ b/pkg/digger/digger.go
@@ -81,9 +81,10 @@ func RunCommandsPerProject(commandsPerProject []ProjectCommand, repoOwner string
 			}
 
 			commandRunner := CommandRunner{}
-
 			diggerExecutor := DiggerExecutor{
 				projectCommands.ProjectName,
+				projectCommands.StateEnvVars,
+				projectCommands.CommandEnvVars,
 				projectCommands.ApplyStage,
 				projectCommands.PlanStage,
 				commandRunner,
@@ -186,6 +187,8 @@ type ProjectCommand struct {
 	Commands         []string
 	ApplyStage       *configuration.Stage
 	PlanStage        *configuration.Stage
+	StateEnvVars     map[string]string
+	CommandEnvVars   map[string]string
 }
 
 func ConvertGithubEventToCommands(event models.Event, impactedProjects []configuration.Project, workflows map[string]configuration.Workflow) ([]ProjectCommand, error) {
@@ -199,6 +202,9 @@ func ConvertGithubEventToCommands(event models.Event, impactedProjects []configu
 			if !ok {
 				workflow = *defaultWorkflow()
 			}
+
+			stateEnvVars, commandEnvVars := collectEnvVars(workflow.EnvVars)
+
 			if event.Action == "closed" && event.PullRequest.Merged && event.PullRequest.Base.Ref == event.Repository.DefaultBranch {
 				commandsPerProject = append(commandsPerProject, ProjectCommand{
 					ProjectName:      project.Name,
@@ -208,6 +214,8 @@ func ConvertGithubEventToCommands(event models.Event, impactedProjects []configu
 					Commands:         workflow.Configuration.OnCommitToDefault,
 					ApplyStage:       workflow.Apply,
 					PlanStage:        workflow.Plan,
+					CommandEnvVars:   commandEnvVars,
+					StateEnvVars:     stateEnvVars,
 				})
 			} else if event.Action == "opened" || event.Action == "reopened" || event.Action == "synchronize" {
 				commandsPerProject = append(commandsPerProject, ProjectCommand{
@@ -218,6 +226,8 @@ func ConvertGithubEventToCommands(event models.Event, impactedProjects []configu
 					Commands:         workflow.Configuration.OnPullRequestPushed,
 					ApplyStage:       workflow.Apply,
 					PlanStage:        workflow.Plan,
+					CommandEnvVars:   commandEnvVars,
+					StateEnvVars:     stateEnvVars,
 				})
 			} else if event.Action == "closed" {
 				commandsPerProject = append(commandsPerProject, ProjectCommand{
@@ -228,6 +238,8 @@ func ConvertGithubEventToCommands(event models.Event, impactedProjects []configu
 					Commands:         workflow.Configuration.OnPullRequestClosed,
 					ApplyStage:       workflow.Apply,
 					PlanStage:        workflow.Plan,
+					CommandEnvVars:   commandEnvVars,
+					StateEnvVars:     stateEnvVars,
 				})
 			}
 		}
@@ -243,6 +255,9 @@ func ConvertGithubEventToCommands(event models.Event, impactedProjects []configu
 					if !ok {
 						workflow = *defaultWorkflow()
 					}
+
+					stateEnvVars, commandEnvVars := collectEnvVars(workflow.EnvVars)
+
 					workspace := project.Workspace
 					workspaceOverride, err := parseWorkspace(event.Comment.Body)
 					if err != nil {
@@ -259,6 +274,8 @@ func ConvertGithubEventToCommands(event models.Event, impactedProjects []configu
 						Commands:         []string{command},
 						ApplyStage:       workflow.Apply,
 						PlanStage:        workflow.Plan,
+						CommandEnvVars:   commandEnvVars,
+						StateEnvVars:     stateEnvVars,
 					})
 				}
 			}
@@ -269,6 +286,29 @@ func ConvertGithubEventToCommands(event models.Event, impactedProjects []configu
 	}
 }
 
+func collectEnvVars(envs configuration.EnvVars) (map[string]string, map[string]string) {
+	stateEnvVars := map[string]string{}
+
+	for _, envvar := range envs.State {
+		if envvar.Value != "" {
+			stateEnvVars[envvar.Name] = envvar.Value
+		} else if envvar.ValueFrom != "" {
+			stateEnvVars[envvar.Name] = os.Getenv(envvar.ValueFrom)
+		}
+	}
+
+	commandEnvVars := map[string]string{}
+
+	for _, envvar := range envs.Commands {
+		if envvar.Value != "" {
+			commandEnvVars[envvar.Name] = envvar.Value
+		} else if envvar.ValueFrom != "" {
+			commandEnvVars[envvar.Name] = os.Getenv(envvar.ValueFrom)
+		}
+	}
+	return stateEnvVars, commandEnvVars
+}
+
 func parseWorkspace(comment string) (string, error) {
 	re := regexp.MustCompile(`-w(?:\s+(\S+)|$)`)
 	matches := re.FindAllStringSubmatch(comment, -1)
@@ -299,6 +339,8 @@ func parseProjectName(comment string) string {
 
 type DiggerExecutor struct {
 	projectName       string
+	stateEnvVars      map[string]string
+	commandEnvVars    map[string]string
 	applyStage        *configuration.Stage
 	planStage         *configuration.Stage
 	commandRunner     CommandRun
@@ -363,7 +405,7 @@ func (d DiggerExecutor) Plan(prNumber int) error {
 		}
 		for _, step := range planSteps {
 			if step.Action == "init" {
-				_, _, err := d.terraformExecutor.Init(step.ExtraArgs)
+				_, _, err := d.terraformExecutor.Init(step.ExtraArgs, d.stateEnvVars)
 				if err != nil {
 					return fmt.Errorf("error running init: %v", err)
 				}
@@ -371,7 +413,7 @@ func (d DiggerExecutor) Plan(prNumber int) error {
 			if step.Action == "plan" {
 				planArgs := []string{"-out", d.planFileName()}
 				planArgs = append(planArgs, step.ExtraArgs...)
-				isNonEmptyPlan, stdout, stderr, err := d.terraformExecutor.Plan(planArgs)
+				isNonEmptyPlan, stdout, stderr, err := d.terraformExecutor.Plan(planArgs, d.commandEnvVars)
 				if err != nil {
 					return fmt.Errorf("error executing plan: %v", err)
 				}
@@ -435,13 +477,13 @@ func (d DiggerExecutor) Apply(prNumber int) error {
 
 			for _, step := range applySteps {
 				if step.Action == "init" {
-					_, _, err := d.terraformExecutor.Init(step.ExtraArgs)
+					_, _, err := d.terraformExecutor.Init(step.ExtraArgs, d.stateEnvVars)
 					if err != nil {
 						return fmt.Errorf("error running init: %v", err)
 					}
 				}
 				if step.Action == "apply" {
-					stdout, stderr, err := d.terraformExecutor.Apply(step.ExtraArgs, plansFilename)
+					stdout, stderr, err := d.terraformExecutor.Apply(step.ExtraArgs, plansFilename, d.commandEnvVars)
 					applyOutput := cleanupTerraformApply(true, err, stdout, stderr)
 					comment := utils.GetTerraformOutputAsCollapsibleComment("Apply for **"+d.lock.LockId()+"**", applyOutput)
 					d.prManager.PublishComment(prNumber, comment)
diff --git a/pkg/terraform/tf.go b/pkg/terraform/tf.go
index 4b1d23e0..78762679 100644
--- a/pkg/terraform/tf.go
+++ b/pkg/terraform/tf.go
@@ -10,9 +10,9 @@ import (
 )
 
 type TerraformExecutor interface {
-	Init([]string) (string, string, error)
-	Apply([]string, *string) (string, string, error)
-	Plan([]string) (bool, string, string, error)
+	Init([]string, map[string]string) (string, string, error)
+	Apply([]string, *string, map[string]string) (string, string, error)
+	Plan([]string, map[string]string) (bool, string, string, error)
 }
 
 type Terragrunt struct {
@@ -24,27 +24,27 @@ type Terraform struct {
 	Workspace  string
 }
 
-func (terragrunt Terragrunt) Init(params []string) (string, string, error) {
-	return terragrunt.runTerragruntCommand("init", params...)
+func (terragrunt Terragrunt) Init(params []string, envs map[string]string) (string, string, error) {
+	return terragrunt.runTerragruntCommand("init", envs, params...)
 
 }
 
-func (terragrunt Terragrunt) Apply(params []string, plan *string) (string, string, error) {
+func (terragrunt Terragrunt) Apply(params []string, plan *string, envs map[string]string) (string, string, error) {
 	params = append(params, "--auto-approve")
 	params = append(params, "--terragrunt-non-interactive")
 	if plan != nil {
 		params = append(params, *plan)
 	}
-	stdout, stderr, err := terragrunt.runTerragruntCommand("apply", params...)
+	stdout, stderr, err := terragrunt.runTerragruntCommand("apply", envs, params...)
 	return stdout, stderr, err
 }
 
-func (terragrunt Terragrunt) Plan(params []string) (bool, string, string, error) {
-	stdout, stderr, err := terragrunt.runTerragruntCommand("plan", params...)
+func (terragrunt Terragrunt) Plan(params []string, envs map[string]string) (bool, string, string, error) {
+	stdout, stderr, err := terragrunt.runTerragruntCommand("plan", envs, params...)
 	return true, stdout, stderr, err
 }
 
-func (terragrunt Terragrunt) runTerragruntCommand(command string, arg ...string) (string, string, error) {
+func (terragrunt Terragrunt) runTerragruntCommand(command string, envs map[string]string, arg ...string) (string, string, error) {
 	args := []string{command}
 	args = append(args, arg...)
 	args = append(args, "--terragrunt-working-dir", terragrunt.WorkingDir)
@@ -53,6 +53,11 @@ func (terragrunt Terragrunt) runTerragruntCommand(command string, arg ...string)
 	env := os.Environ()
 	env = append(env, "TF_CLI_ARGS=-no-color")
 	env = append(env, "TF_IN_AUTOMATION=true")
+
+	for k, v := range envs {
+		env = append(env, fmt.Sprintf("%s=%s", k, v))
+	}
+
 	cmd.Env = env
 
 	var stdout, stderr bytes.Buffer
@@ -69,23 +74,23 @@ func (terragrunt Terragrunt) runTerragruntCommand(command string, arg ...string)
 	return stdout.String(), stderr.String(), err
 }
 
-func (tf Terraform) Init(params []string) (string, string, error) {
+func (tf Terraform) Init(params []string, envs map[string]string) (string, string, error) {
 	params = append(params, "-upgrade=true")
 	params = append(params, "-input=false")
 	params = append(params, "-no-color")
-	stdout, stderr, _, err := tf.runTerraformCommand("init", params...)
+	stdout, stderr, _, err := tf.runTerraformCommand("init", envs, params...)
 	return stdout, stderr, err
 }
 
-func (tf Terraform) Apply(params []string, plan *string) (string, string, error) {
-	workspace, _, _, err := tf.runTerraformCommand("workspace", "show")
+func (tf Terraform) Apply(params []string, plan *string, envs map[string]string) (string, string, error) {
+	workspace, _, _, err := tf.runTerraformCommand("workspace", envs, "show")
 
 	if err != nil {
 		return "", "", err
 	}
 
 	if strings.TrimSpace(workspace) != tf.Workspace {
-		_, _, _, err = tf.runTerraformCommand("workspace", "new", tf.Workspace)
+		_, _, _, err = tf.runTerraformCommand("workspace", envs, "new", tf.Workspace)
 		if err != nil {
 			return "", "", err
 		}
@@ -94,18 +99,17 @@ func (tf Terraform) Apply(params []string, plan *string) (string, string, error)
 	if plan != nil {
 		params = append(params, *plan)
 	}
-	stdout, stderr, _, err := tf.runTerraformCommand("apply", params...)
+	stdout, stderr, _, err := tf.runTerraformCommand("apply", envs, params...)
 	if err != nil {
 		return "", "", err
 	}
 	return stdout, stderr, nil
 }
 
-func (tf Terraform) runTerraformCommand(command string, arg ...string) (string, string, int, error) {
+func (tf Terraform) runTerraformCommand(command string, envs map[string]string, arg ...string) (string, string, int, error) {
 	args := []string{"-chdir=" + tf.WorkingDir}
 	args = append(args, command)
 	args = append(args, arg...)
-	fmt.Printf("Running terraform %v", args)
 
 	var stdout, stderr bytes.Buffer
 	mwout := io.MultiWriter(os.Stdout, &stdout)
@@ -113,6 +117,11 @@ func (tf Terraform) runTerraformCommand(command string, arg ...string) (string,
 
 	cmd := exec.Command("terraform", args...)
 
+	env := os.Environ()
+	for k, v := range envs {
+		env = append(env, fmt.Sprintf("%s=%s", k, v))
+	}
+	cmd.Env = env
 	cmd.Stdout = mwout
 	cmd.Stderr = mwerr
 
@@ -145,20 +154,20 @@ func (sw *StdWriter) GetString() string {
 	return s
 }
 
-func (tf Terraform) Plan(params []string) (bool, string, string, error) {
-	workspace, _, _, err := tf.runTerraformCommand("workspace", "show")
+func (tf Terraform) Plan(params []string, envs map[string]string) (bool, string, string, error) {
+	workspace, _, _, err := tf.runTerraformCommand("workspace", envs, "show")
 
 	if err != nil {
 		return false, "", "", err
 	}
 	if strings.TrimSpace(workspace) != tf.Workspace {
-		_, _, _, err = tf.runTerraformCommand("workspace", "new", tf.Workspace)
+		_, _, _, err = tf.runTerraformCommand("workspace", envs, "new", tf.Workspace)
 		if err != nil {
 			return false, "", "", err
 		}
 	}
 	params = append(append(params, "-input=false"), "-no-color")
-	stdout, stderr, statusCode, err := tf.runTerraformCommand("plan", params...)
+	stdout, stderr, statusCode, err := tf.runTerraformCommand("plan", envs, params...)
 	if err != nil {
 		return false, "", "", err
 	}


Test patch:
diff --git a/pkg/configuration/digger_config_test.go b/pkg/configuration/digger_config_test.go
index 55930eb4..b5b2a3bf 100644
--- a/pkg/configuration/digger_config_test.go
+++ b/pkg/configuration/digger_config_test.go
@@ -116,6 +116,56 @@ workflows:
 	assert.Equal(t, Step{Action: "run", Value: "echo \"hello\""}, dg.Workflows["myworkflow"].Plan.Steps[0], "parsed struct does not match expected struct")
 }
 
+func TestEnvVarsConfiguration(t *testing.T) {
+	tempDir, teardown := setUp()
+	defer teardown()
+
+	diggerCfg := `
+projects:
+- name: dev
+  branch: /main/
+  dir: .
+  workspace: default
+  terragrunt: false
+  workflow: myworkflow
+workflows:
+  myworkflow:
+    plan:
+      steps:
+      - init:
+          extra_args: ["-lock=false"]
+      - plan:
+          extra_args: ["-lock=false"]
+      - run: echo "hello"
+    apply:
+      steps:
+      - apply:
+          extra_args: ["-lock=false"]
+    workflow_configuration:
+      on_pull_request_pushed: [digger plan]
+      on_pull_request_closed: [digger unlock]
+      on_commit_to_default: [digger apply]
+    env_vars:
+      state:
+      - name: TF_VAR_state
+        value: s3://mybucket/terraform.tfstate
+      commands:
+      - name: TF_VAR_command
+        value: plan
+`
+	deleteFile := createFile(path.Join(tempDir, "digger.yaml"), diggerCfg)
+	defer deleteFile()
+
+	dg, err := NewDiggerConfig(tempDir, &FileSystemDirWalker{})
+	assert.NoError(t, err, "expected error to be nil")
+	assert.Equal(t, []EnvVarConfig{
+		{Name: "TF_VAR_state", Value: "s3://mybucket/terraform.tfstate"},
+	}, dg.Workflows["myworkflow"].EnvVars.State, "parsed struct does not match expected struct")
+	assert.Equal(t, []EnvVarConfig{
+		{Name: "TF_VAR_command", Value: "plan"},
+	}, dg.Workflows["myworkflow"].EnvVars.Commands, "parsed struct does not match expected struct")
+}
+
 func TestDefaultValuesForWorkflowConfiguration(t *testing.T) {
 	tempDir, teardown := setUp()
 	defer teardown()
diff --git a/pkg/digger/digger_test.go b/pkg/digger/digger_test.go
index 71b56b7e..9f33753c 100644
--- a/pkg/digger/digger_test.go
+++ b/pkg/digger/digger_test.go
@@ -30,12 +30,12 @@ type MockTerraformExecutor struct {
 	Commands []RunInfo
 }
 
-func (m *MockTerraformExecutor) Init(params []string) (string, string, error) {
+func (m *MockTerraformExecutor) Init(params []string, envs map[string]string) (string, string, error) {
 	m.Commands = append(m.Commands, RunInfo{"Init", strings.Join(params, " "), time.Now()})
 	return "", "", nil
 }
 
-func (m *MockTerraformExecutor) Apply(params []string, plan *string) (string, string, error) {
+func (m *MockTerraformExecutor) Apply(params []string, plan *string, envs map[string]string) (string, string, error) {
 	if plan != nil {
 		params = append(params, *plan)
 	}
@@ -43,7 +43,7 @@ func (m *MockTerraformExecutor) Apply(params []string, plan *string) (string, st
 	return "", "", nil
 }
 
-func (m *MockTerraformExecutor) Plan(params []string) (bool, string, string, error) {
+func (m *MockTerraformExecutor) Plan(params []string, envs map[string]string) (bool, string, string, error) {
 	m.Commands = append(m.Commands, RunInfo{"Plan", strings.Join(params, " "), time.Now()})
 	return true, "", "", nil
 }
diff --git a/pkg/integration/integration_test.go b/pkg/integration/integration_test.go
index 4da2419a..a5a854ff 100644
--- a/pkg/integration/integration_test.go
+++ b/pkg/integration/integration_test.go
@@ -388,7 +388,7 @@ func TestHappyPath(t *testing.T) {
 	//  new pr should lock the project
 	impactedProjects, prNumber, _, err := digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	zipManager := utils.Zipper{}
 	planStorage := &utils.GithubPlanStorage{
@@ -423,7 +423,7 @@ func TestHappyPath(t *testing.T) {
 	// 'digger plan' comment should trigger terraform execution
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
@@ -437,7 +437,7 @@ func TestHappyPath(t *testing.T) {
 	// 'digger apply' comment should trigger terraform execution and unlock the project
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
@@ -461,7 +461,7 @@ func TestHappyPath(t *testing.T) {
 
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
@@ -539,7 +539,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 	// no files changed, no locks
 	impactedProjects, prNumber, _, err := digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 
 	zipManager := utils.Zipper{}
@@ -574,7 +574,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 	// 'digger plan' comment should trigger terraform execution
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
 	assert.NoError(t, err)
@@ -588,7 +588,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 	// 'digger apply' comment should trigger terraform execution and unlock the project
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
 	assert.NoError(t, err)
@@ -612,7 +612,7 @@ func TestMultiEnvHappyPath(t *testing.T) {
 
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, &dynamoDbLock, planStorage, dir)
 	assert.NoError(t, err)
@@ -754,7 +754,7 @@ workflows:
 	//  new pr should lock the project
 	impactedProjects, prNumber, _, err := digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err := digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 
 	zipManager := utils.Zipper{}
@@ -790,7 +790,7 @@ workflows:
 	// 'digger plan' comment should trigger terraform execution
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
@@ -804,7 +804,7 @@ workflows:
 	// 'digger apply' comment should trigger terraform execution and unlock the project
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
@@ -827,7 +827,7 @@ workflows:
 
 	impactedProjects, prNumber, _, err = digger.ProcessGitHubEvent(ghEvent, diggerConfig, githubPrService)
 	assert.NoError(t, err)
-	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, map[string]configuration.Workflow{})
+	commandsToRunPerProject, err = digger.ConvertGithubEventToCommands(ghEvent, impactedProjects, diggerConfig.Workflows)
 	assert.NoError(t, err)
 	_, err = digger.RunCommandsPerProject(commandsToRunPerProject, repoOwner, repositoryName, eventName, prNumber, githubPrService, lock, planStorage, dir)
 	assert.NoError(t, err)
diff --git a/pkg/terraform/tf_test.go b/pkg/terraform/tf_test.go
index 66bfe22e..4a8f5969 100644
--- a/pkg/terraform/tf_test.go
+++ b/pkg/terraform/tf_test.go
@@ -19,8 +19,8 @@ func TestExecuteTerraformPlan(t *testing.T) {
 	CreateValidTerraformTestFile(dir)
 
 	tf := Terraform{WorkingDir: dir, Workspace: "dev"}
-	tf.Init([]string{})
-	_, _, _, err := tf.Plan([]string{})
+	tf.Init([]string{}, map[string]string{})
+	_, _, _, err := tf.Plan([]string{}, map[string]string{})
 	assert.NoError(t, err)
 }
 
@@ -36,8 +36,8 @@ func TestExecuteTerraformApply(t *testing.T) {
 	CreateValidTerraformTestFile(dir)
 
 	tf := Terraform{WorkingDir: dir, Workspace: "dev"}
-	tf.Init([]string{})
-	_, _, _, err := tf.Plan([]string{})
+	tf.Init([]string{}, map[string]string{})
+	_, _, _, err := tf.Plan([]string{}, map[string]string{})
 	assert.NoError(t, err)
 }
 
@@ -53,11 +53,11 @@ func TestExecuteTerraformApplyDefaultWorkspace(t *testing.T) {
 	CreateValidTerraformTestFile(dir)
 
 	tf := Terraform{WorkingDir: dir, Workspace: "default"}
-	tf.Init([]string{})
+	tf.Init([]string{}, map[string]string{})
 	var planArgs []string
 	planArgs = append(planArgs, "-out", "plan.tfplan")
-	tf.Plan(planArgs)
+	tf.Plan(planArgs, map[string]string{})
 	plan := "plan.tfplan"
-	_, _, err := tf.Apply([]string{}, &plan)
+	_, _, err := tf.Apply([]string{}, &plan, map[string]string{})
 	assert.NoError(t, err)
 }