provisioner/local-exec: Allow passing environment variables

This commit is contained in:
Kristiyan Nikolov 2018-03-06 01:58:49 +02:00 committed by Martin Atkins
parent 6f98b4d4be
commit 999f9096c1
3 changed files with 64 additions and 3 deletions

View File

@ -28,17 +28,19 @@ func Provisioner() terraform.ResourceProvisioner {
Type: schema.TypeString,
Required: true,
},
"interpreter": &schema.Schema{
Type: schema.TypeList,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
},
"working_dir": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"environment": &schema.Schema{
Type: schema.TypeMap,
Optional: true,
},
},
ApplyFunc: applyFn,
@ -50,11 +52,20 @@ func applyFn(ctx context.Context) error {
o := ctx.Value(schema.ProvOutputKey).(terraform.UIOutput)
command := data.Get("command").(string)
if command == "" {
return fmt.Errorf("local-exec provisioner command must be a non-empty string")
}
// Execute the command with env
environment := data.Get("environment").(map[string]interface{})
var env []string
env = make([]string, len(environment))
for k := range environment {
entry := fmt.Sprintf("%s=%s", k, environment[k].(string))
env = append(env, entry)
}
// Execute the command using a shell
interpreter := data.Get("interpreter").([]interface{})
@ -85,6 +96,10 @@ func applyFn(ctx context.Context) error {
return fmt.Errorf("failed to initialize pipe for output: %s", err)
}
var cmdEnv []string
cmdEnv = os.Environ()
cmdEnv = append(cmdEnv, env...)
// Setup the command
cmd := exec.CommandContext(ctx, cmdargs[0], cmdargs[1:]...)
cmd.Stderr = pw
@ -93,6 +108,9 @@ func applyFn(ctx context.Context) error {
// If Dir is the empty string (this is default), runs the command
// in the calling process's current directory.
cmd.Dir = workingdir
// Env specifies the environment of the command.
// By default will use the calling process's environment
cmd.Env = cmdEnv
output, _ := circbuf.NewBuffer(maxBufSize)

View File

@ -174,3 +174,27 @@ func TestResourceProvider_ApplyCustomWorkingDirectory(t *testing.T) {
t.Errorf("wrong output\ngot: %s\nwant: %s", got, want)
}
}
func TestResourceProvider_ApplyCustomEnv(t *testing.T) {
c := testConfig(t, map[string]interface{}{
"command": "echo $FOO $BAR $BAZ",
"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"
if got != want {
t.Errorf("wrong output\ngot: %s\nwant: %s", got, want)
}
}

View File

@ -51,6 +51,9 @@ The following arguments are supported:
form "/bin/bash", "-c", "echo foo". If `interpreter` is unspecified,
sensible defaults will be chosen based on the system OS.
* `environment` - (Optional) block of key value pairs representing the
environment of the executed command. inherits the current process environment.
### Interpreter Examples
```hcl
@ -70,3 +73,19 @@ resource "null_resource" "example2" {
}
}
```
```hcl
resource "aws_instance" "web" {
# ...
provisioner "local-exec" {
command = "echo $FOO $BAR $BAZ >> env_vars.txt"
environment {
FOO = "bar"
BAR = 1
BAZ = "true"
}
}
}
```