From b94390413ead474dba024253286846cb07e99f30 Mon Sep 17 00:00:00 2001 From: Adam Lewandowski Date: Fri, 25 Oct 2019 21:40:51 -0400 Subject: [PATCH 1/2] Support passthrough of system env for local-exec provisioner --- .../local-exec/resource_provisioner.go | 18 +++++++++- .../local-exec/resource_provisioner_test.go | 34 +++++++++++++++++++ .../provisioners/local-exec.html.markdown | 5 +++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/builtin/provisioners/local-exec/resource_provisioner.go b/builtin/provisioners/local-exec/resource_provisioner.go index f0ba28f342fd..b6dda724e613 100644 --- a/builtin/provisioners/local-exec/resource_provisioner.go +++ b/builtin/provisioners/local-exec/resource_provisioner.go @@ -7,6 +7,7 @@ import ( "os" "os/exec" "runtime" + "strings" "github.com/armon/circbuf" "github.com/hashicorp/terraform/helper/schema" @@ -41,6 +42,10 @@ func Provisioner() terraform.ResourceProvisioner { Type: schema.TypeMap, Optional: true, }, + "system_environment": &schema.Schema{ + Type: schema.TypeBool, + Optional: true, + }, }, ApplyFunc: applyFn, @@ -57,7 +62,18 @@ func applyFn(ctx context.Context) error { } // Execute the command with env - environment := data.Get("environment").(map[string]interface{}) + environment := make(map[string]interface{}) + // Start with the system env (if desired) + if data.Get("system_environment").(bool) { + for _, e := range os.Environ() { + pair := strings.SplitN(e, "=", 2) + environment[pair[0]] = pair[1] + } + } + // Apply the explicitly specified environment + for k, v := range data.Get("environment").(map[string]interface{}) { + environment[k] = v + } var env []string for k := range environment { diff --git a/builtin/provisioners/local-exec/resource_provisioner_test.go b/builtin/provisioners/local-exec/resource_provisioner_test.go index 8718d4dabb47..b48b39dee355 100644 --- a/builtin/provisioners/local-exec/resource_provisioner_test.go +++ b/builtin/provisioners/local-exec/resource_provisioner_test.go @@ -192,3 +192,37 @@ func TestResourceProvider_ApplyCustomEnv(t *testing.T) { t.Errorf("wrong output\ngot: %s\nwant: %s", got, want) } } + +func TestResourceProvider_ApplySystemEnv(t *testing.T) { + // Preserve original system env values (if any) + origFoo := os.Getenv("FOO") + defer os.Setenv("FOO", origFoo) + origBam := os.Getenv("BAM") + defer os.Setenv("FOO", origBam) + + os.Setenv("FOO", "SystemFOO") + os.Setenv("BAM", "SystemBAM") + + c := testConfig(t, map[string]interface{}{ + "command": "echo $FOO $BAR $BAZ $BAM", + "system_env": true, + "environment": map[string]interface{}{ + "FOO": "BAR", + "BAR": 1, + "BAZ": "true", + }, + }) + + output := new(terraform.MockUIOutput) + p := Provisioner() + + if err := p.Apply(output, nil, c); err != nil { + t.Fatalf("err: %v", err) + } + + got := strings.TrimSpace(output.OutputMessage) + want := "BAR 1 true SystemBAM" + if got != want { + t.Errorf("wrong output\ngot: %s\nwant: %s", got, want) + } +} diff --git a/website/docs/provisioners/local-exec.html.markdown b/website/docs/provisioners/local-exec.html.markdown index 2f8cf628f4f5..0eb12339e954 100644 --- a/website/docs/provisioners/local-exec.html.markdown +++ b/website/docs/provisioners/local-exec.html.markdown @@ -58,6 +58,11 @@ The following arguments are supported: * `environment` - (Optional) block of key value pairs representing the environment of the executed command. inherits the current process environment. +* `system_environment` - (Optional) If true, the environment of the terraform + process will be passed through to the executed command. Variables explicitly specified + in `environment` will take precedence over any variables inherited from the system + environment. + ### Interpreter Examples ```hcl From 3645108bfa80c3429b3c472dba961e5ca33768a2 Mon Sep 17 00:00:00 2001 From: Adam Lewandowski Date: Fri, 25 Oct 2019 22:06:29 -0400 Subject: [PATCH 2/2] Fix formatting --- builtin/provisioners/local-exec/resource_provisioner_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/provisioners/local-exec/resource_provisioner_test.go b/builtin/provisioners/local-exec/resource_provisioner_test.go index b48b39dee355..68d6e0109001 100644 --- a/builtin/provisioners/local-exec/resource_provisioner_test.go +++ b/builtin/provisioners/local-exec/resource_provisioner_test.go @@ -204,7 +204,7 @@ func TestResourceProvider_ApplySystemEnv(t *testing.T) { os.Setenv("BAM", "SystemBAM") c := testConfig(t, map[string]interface{}{ - "command": "echo $FOO $BAR $BAZ $BAM", + "command": "echo $FOO $BAR $BAZ $BAM", "system_env": true, "environment": map[string]interface{}{ "FOO": "BAR",