Skip to content

Commit

Permalink
Merge pull request #553 from geriBatai/master
Browse files Browse the repository at this point in the history
Add env_vars to extra_arguments terraform block
  • Loading branch information
brikis98 authored Aug 30, 2018
2 parents 27cb4cd + 70d7bcb commit c976367
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 8 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -634,14 +634,19 @@ terragrunt = {
arguments = [
"-lock-timeout=20m"
]
env_vars = {
TF_VAR_var_from_environment = "value"
}
}
}
}
```
Each `extra_arguments` block includes an arbitrary name (in the example above, `retry_lock`), a list of `commands` to
which the extra arguments should be add, a list of `arguments` or `required_var_files` or `optional_var_files` to add.
With the configuration above, when you run `terragrunt apply`, Terragrunt will call Terraform as follows:
You can also pass custom variables using `env_vars` block, which stores environment variables in key value pairs. With
the configuration above, when you run `terragrunt apply`, Terragrunt will call Terraform as follows:
When available, it is preferable to use interpolation functions such as
[get_terraform_commands_that_need_locking](#get_terraform_commands_that_need_locking) and
Expand Down
17 changes: 17 additions & 0 deletions cli/args.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,23 @@ func filterTerraformExtraArgs(terragruntOptions *options.TerragruntOptions, terr
return out
}

func filterTerraformEnvVarsFromExtraArgs(terragruntOptions *options.TerragruntOptions, terragruntConfig *config.TerragruntConfig) map[string]string {
out := map[string]string{}
cmd := util.FirstArg(terragruntOptions.TerraformCliArgs)

for _, arg := range terragruntConfig.Terraform.ExtraArgs {
for _, argcmd := range arg.Commands {
if cmd == argcmd {
for k, v := range arg.EnvVars {
out[k] = v
}
}
}
}

return out
}

func parseEnvironmentVariables(environment []string) map[string]string {
environmentMap := make(map[string]string)

Expand Down
3 changes: 3 additions & 0 deletions cli/cli_app.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ func runTerragruntWithConfig(terragruntOptions *options.TerragruntOptions, terra
// Add extra_arguments to the command
if terragruntConfig.Terraform != nil && terragruntConfig.Terraform.ExtraArgs != nil && len(terragruntConfig.Terraform.ExtraArgs) > 0 {
terragruntOptions.InsertTerraformCliArgs(filterTerraformExtraArgs(terragruntOptions, terragruntConfig)...)
for k, v := range filterTerraformEnvVarsFromExtraArgs(terragruntOptions, terragruntConfig) {
terragruntOptions.Env[k] = v
}
}

if util.FirstArg(terragruntOptions.TerraformCliArgs) == CMD_INIT {
Expand Down
18 changes: 12 additions & 6 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,21 @@ func (conf *TerraformConfig) ValidateHooks() error {

// TerraformExtraArguments sets a list of arguments to pass to Terraform if command fits any in the `Commands` list
type TerraformExtraArguments struct {
Name string `hcl:",key"`
Arguments []string `hcl:"arguments,omitempty"`
RequiredVarFiles []string `hcl:"required_var_files,omitempty"`
OptionalVarFiles []string `hcl:"optional_var_files,omitempty"`
Commands []string `hcl:"commands,omitempty"`
Name string `hcl:",key"`
Arguments []string `hcl:"arguments,omitempty"`
RequiredVarFiles []string `hcl:"required_var_files,omitempty"`
OptionalVarFiles []string `hcl:"optional_var_files,omitempty"`
Commands []string `hcl:"commands,omitempty"`
EnvVars map[string]string `hcl:"env_vars,omitempty"`
}

func (conf *TerraformExtraArguments) String() string {
return fmt.Sprintf("TerraformArguments{Name = %s, Arguments = %v, Commands = %v}", conf.Name, conf.Arguments, conf.Commands)
return fmt.Sprintf(
"TerraformArguments{Name = %s, Arguments = %v, Commands = %v, EnvVars = %v}",
conf.Name,
conf.Arguments,
conf.Commands,
conf.EnvVars)
}

// Return the default path to use for the Terragrunt configuration file. The reason this is a method rather than a
Expand Down
9 changes: 8 additions & 1 deletion config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,10 @@ terragrunt = {
"-var-file=terraform.tfvars",
"-var-file=terraform-secret.tfvars"
]
commands = ["${get_terraform_commands_that_need_vars()}"]
commands = ["${get_terraform_commands_that_need_vars()}"]
env_vars = {
TEST_VAR = "value"
}
}
}
}
Expand All @@ -648,6 +651,10 @@ terragrunt = {
assert.Equal(t,
TERRAFORM_COMMANDS_NEED_VARS,
terragruntConfig.Terraform.ExtraArgs[0].Commands)

assert.Equal(t,
map[string]string{"TEST_VAR": "value"},
terragruntConfig.Terraform.ExtraArgs[0].EnvVars)
}
}

Expand Down
7 changes: 7 additions & 0 deletions test/fixture-env-vars-block/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
variable "custom_var" {
description = "Provided as TF_VAR_custom_var in terraform.tfvars"
}

output "test" {
value = "${var.custom_var}"
}
19 changes: 19 additions & 0 deletions test/fixture-env-vars-block/terraform.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
terragrunt = {
terraform = {
extra_arguments "test" {
commands = ["apply"]
env_vars = {
TF_VAR_custom_var = "I'm set in extra_arguments env_vars"
}
}

extra_arguments "shouldnotapply" {
commands = [ "refresh" ]

env_vars = {
TF_VAR_custom_var = "I'm only set for refresh command, so will be ignored for apply"
}

}
}
}
8 changes: 8 additions & 0 deletions test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const (
TEST_FIXTURE_OUTPUT_ALL = "fixture-output-all"
TEST_FIXTURE_STDOUT = "fixture-download/stdout-test"
TEST_FIXTURE_EXTRA_ARGS_PATH = "fixture-extra-args/"
TEST_FIXTURE_ENV_VARS_BLOCK_PATH = "fixture-env-vars-block/"
TEST_FIXTURE_LOCAL_DOWNLOAD_PATH = "fixture-download/local"
TEST_FIXTURE_REMOTE_DOWNLOAD_PATH = "fixture-download/remote"
TEST_FIXTURE_OVERRIDE_DOWNLOAD_PATH = "fixture-download/override"
Expand Down Expand Up @@ -807,6 +808,13 @@ func TestExtraArgumentsWithEnv(t *testing.T) {
assert.Contains(t, out.String(), "Hello, World!")
}

func TestExtraArgumentsWithEnvVarBlock(t *testing.T) {
out := new(bytes.Buffer)
runTerragruntRedirectOutput(t, fmt.Sprintf("terragrunt apply --terragrunt-non-interactive --terragrunt-working-dir %s", TEST_FIXTURE_ENV_VARS_BLOCK_PATH), out, os.Stderr)
t.Log(out.String())
assert.Contains(t, out.String(), "I'm set in extra_arguments env_vars")
}

func TestExtraArgumentsWithRegion(t *testing.T) {
// Do not use t.Parallel() on this test, it will infers with the other TestExtraArguments.* tests
out := new(bytes.Buffer)
Expand Down

0 comments on commit c976367

Please sign in to comment.