From 04325c2234ac0ddbcbdbad22d12005b1a8df6c6b Mon Sep 17 00:00:00 2001 From: Simas Cepaitis Date: Wed, 29 Aug 2018 13:48:44 +0300 Subject: [PATCH 1/6] Add env_vars to extra_arguments terraform block --- cli/args.go | 12 ++++++++++++ cli/cli_app.go | 3 +++ config/config.go | 18 ++++++++++++------ config/config_test.go | 9 ++++++++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/cli/args.go b/cli/args.go index 79db13e925..0f7add14a9 100644 --- a/cli/args.go +++ b/cli/args.go @@ -142,6 +142,18 @@ func filterTerraformExtraArgs(terragruntOptions *options.TerragruntOptions, terr return out } +func filterTerraformEnvVars(terragruntOptions *options.TerragruntOptions, terragruntConfig *config.TerragruntConfig) map[string]string { + out := map[string]string{} + + for _, arg := range terragruntConfig.Terraform.ExtraArgs { + for k, v := range arg.EnvVars { + out[k] = v + } + } + + return out +} + func parseEnvironmentVariables(environment []string) map[string]string { environmentMap := make(map[string]string) diff --git a/cli/cli_app.go b/cli/cli_app.go index 68a68457ed..4eeb458224 100644 --- a/cli/cli_app.go +++ b/cli/cli_app.go @@ -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 filterTerraformEnvVars(terragruntOptions, terragruntConfig) { + terragruntOptions.Env[k] = v + } } if util.FirstArg(terragruntOptions.TerraformCliArgs) == CMD_INIT { diff --git a/config/config.go b/config/config.go index 2d4b5a8792..90615e86b5 100644 --- a/config/config.go +++ b/config/config.go @@ -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 diff --git a/config/config_test.go b/config/config_test.go index 6f3d0f85fa..b0412eb0e4 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -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" + } } } } @@ -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) } } From 7ab9dbdb20fe81bc502e1b17c63bd9b5f88310f6 Mon Sep 17 00:00:00 2001 From: Simas Cepaitis Date: Wed, 29 Aug 2018 15:14:48 +0300 Subject: [PATCH 2/6] Add integration test --- test/fixture-env-vars-block/main.tf | 7 +++++++ test/fixture-env-vars-block/terraform.tfvars | 9 +++++++++ test/integration_test.go | 8 ++++++++ 3 files changed, 24 insertions(+) create mode 100644 test/fixture-env-vars-block/main.tf create mode 100644 test/fixture-env-vars-block/terraform.tfvars diff --git a/test/fixture-env-vars-block/main.tf b/test/fixture-env-vars-block/main.tf new file mode 100644 index 0000000000..27d087cad6 --- /dev/null +++ b/test/fixture-env-vars-block/main.tf @@ -0,0 +1,7 @@ +variable "custom_var" { + description = "Provided as TF_VAR_custom_var in terraform.tfvars" +} + +output "test" { + value = "${var.custom_var}" +} diff --git a/test/fixture-env-vars-block/terraform.tfvars b/test/fixture-env-vars-block/terraform.tfvars new file mode 100644 index 0000000000..e650792f80 --- /dev/null +++ b/test/fixture-env-vars-block/terraform.tfvars @@ -0,0 +1,9 @@ +terragrunt = { + terraform = { + extra_arguments "test" { + env_vars = { + TF_VAR_custom_var = "I'm set in extra_arguments env_vars" + } + } + } +} diff --git a/test/integration_test.go b/test/integration_test.go index e14863a94b..310f65bd37 100644 --- a/test/integration_test.go +++ b/test/integration_test.go @@ -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" @@ -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) From 8fcf74fa6893404ff1b223ba473abc343a4ef1fe Mon Sep 17 00:00:00 2001 From: Simas Cepaitis Date: Wed, 29 Aug 2018 15:19:20 +0300 Subject: [PATCH 3/6] Add documentation block about env_vars --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9069e2430b..25117f69bb 100644 --- a/README.md +++ b/README.md @@ -631,6 +631,10 @@ terragrunt = { arguments = [ "-lock-timeout=20m" ] + + env_vars = { + TF_VAR_var_from_environment = "value" + } } } } @@ -638,7 +642,8 @@ terragrunt = { 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 From c7b4b0cabf2ebfea0a5d3c609c3639047ed3d6ba Mon Sep 17 00:00:00 2001 From: Simas Cepaitis Date: Wed, 29 Aug 2018 15:22:47 +0300 Subject: [PATCH 4/6] Rename env_var filter to filterTerraformEnvVarsFromExtraArgs --- cli/args.go | 2 +- cli/cli_app.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/args.go b/cli/args.go index 0f7add14a9..c4d57dda1a 100644 --- a/cli/args.go +++ b/cli/args.go @@ -142,7 +142,7 @@ func filterTerraformExtraArgs(terragruntOptions *options.TerragruntOptions, terr return out } -func filterTerraformEnvVars(terragruntOptions *options.TerragruntOptions, terragruntConfig *config.TerragruntConfig) map[string]string { +func filterTerraformEnvVarsFromExtraArgs(terragruntOptions *options.TerragruntOptions, terragruntConfig *config.TerragruntConfig) map[string]string { out := map[string]string{} for _, arg := range terragruntConfig.Terraform.ExtraArgs { diff --git a/cli/cli_app.go b/cli/cli_app.go index 4eeb458224..7514e2dd9c 100644 --- a/cli/cli_app.go +++ b/cli/cli_app.go @@ -321,7 +321,7 @@ 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 filterTerraformEnvVars(terragruntOptions, terragruntConfig) { + for k, v := range filterTerraformEnvVarsFromExtraArgs(terragruntOptions, terragruntConfig) { terragruntOptions.Env[k] = v } } From d6a67ab7be4ab4802dd64a4f5b2e13b50cb4848b Mon Sep 17 00:00:00 2001 From: Yevgeniy Brikman Date: Wed, 29 Aug 2018 22:35:58 +0100 Subject: [PATCH 5/6] Fix minor typo in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 25117f69bb..e72ee166ef 100644 --- a/README.md +++ b/README.md @@ -642,7 +642,7 @@ terragrunt = { 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. -You can also pass custom variables using `env_vars` block, which stores environment variables in key value pairs.With +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 From 70d7bcb3e979d7e3d3e791826eca0ac51e2c7376 Mon Sep 17 00:00:00 2001 From: Simas Cepaitis Date: Thu, 30 Aug 2018 13:00:32 +0300 Subject: [PATCH 6/6] Filter out env vars for specific commands only --- cli/args.go | 9 +++++++-- test/fixture-env-vars-block/terraform.tfvars | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cli/args.go b/cli/args.go index c4d57dda1a..d806e84b71 100644 --- a/cli/args.go +++ b/cli/args.go @@ -144,10 +144,15 @@ func filterTerraformExtraArgs(terragruntOptions *options.TerragruntOptions, terr 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 k, v := range arg.EnvVars { - out[k] = v + for _, argcmd := range arg.Commands { + if cmd == argcmd { + for k, v := range arg.EnvVars { + out[k] = v + } + } } } diff --git a/test/fixture-env-vars-block/terraform.tfvars b/test/fixture-env-vars-block/terraform.tfvars index e650792f80..94036d9bb9 100644 --- a/test/fixture-env-vars-block/terraform.tfvars +++ b/test/fixture-env-vars-block/terraform.tfvars @@ -1,9 +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" + } + + } } }