Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changes/unreleased/FEATURES-20251103-153952.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kind: FEATURES
body: 'action/local_command: New action that invokes an executable on the local machine.'
time: 2025-11-03T15:39:52.741799-05:00
custom:
Issue: "450"
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
- name: Set up Terraform
uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd # v3.1.2
with:
# TODO: Remove once Terraform 1.14 GA is released
terraform_version: 1.14.0-rc2
terraform_wrapper: false

- name: Generate
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ website/vendor
# Test exclusions
!command/test-fixtures/**/*.tfstate
!command/test-fixtures/**/.terraform/

.vscode
79 changes: 79 additions & 0 deletions docs/actions/command.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
page_title: "local_command Action - terraform-provider-local"
subcategory: ""
description: |-
Invokes an executable on the local machine. All environment variables visible to the Terraform process are passed through to the child process. After the child process successfully executes, the stdout will be returned for Terraform to display to the user.
Any non-zero exit code will be treated as an error and will return a diagnostic to Terraform containing the stderr message if available.
---

# local_command (Action)

Invokes an executable on the local machine. All environment variables visible to the Terraform process are passed through to the child process. After the child process successfully executes, the `stdout` will be returned for Terraform to display to the user.

Any non-zero exit code will be treated as an error and will return a diagnostic to Terraform containing the `stderr` message if available.

## Example Usage

For the following bash script (`example_script.sh`):
```bash
#!/bin/bash

DATA=$(</dev/stdin)
echo "stdin: $DATA, args: $@"
```

Here is an example configuration that will run the script after a resource is created:

```terraform
resource "terraform_data" "test" {
lifecycle {
action_trigger {
events = [after_create]
actions = [action.local_command.bash_example]
}
}
}

action "local_command" "bash_example" {
config {
command = "bash"
arguments = ["example_script.sh", "arg1", "arg2"]
stdin = jsonencode({
"key1" : "value1"
"key2" : "value2"
})
}
}
```

The `stdout` will be displayed when the action is invoked:
```bash
$ terraform apply -auto-approve

# .. Terraform CLI output truncated for example purposes

Plan: 1 to add, 0 to change, 0 to destroy. Actions: 1 to invoke.
terraform_data.test: Creating...
terraform_data.test: Creation complete after 0s [id=4b41b541-5550-590a-9949-657e91baa346]
Action started: action.local_command.bash_example (triggered by terraform_data.test)
Action action.local_command.bash_example (triggered by terraform_data.test):

stdin: {"key1":"value1","key2":"value2"}, args: arg1 arg2


Action complete: action.local_command.bash_example (triggered by terraform_data.test)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

<!-- action schema generated by tfplugindocs -->
## Schema

### Required

- `command` (String) Executable name to be discovered on the PATH or absolute path to executable.

### Optional

- `arguments` (List of String) Arguments to be passed to the given command. Any `null` arguments will be removed from the list.
- `stdin` (String) Data to be passed to the given command's standard input.
- `working_directory` (String) The directory path where the command should be executed, either an absolute path or relative to the Terraform working directory. If not provided, defaults to the Terraform working directory.
19 changes: 19 additions & 0 deletions examples/actions/local_command/action.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resource "terraform_data" "test" {
lifecycle {
action_trigger {
events = [after_create]
actions = [action.local_command.bash_example]
}
}
}

action "local_command" "bash_example" {
config {
command = "bash"
arguments = ["example_script.sh", "arg1", "arg2"]
stdin = jsonencode({
"key1" : "value1"
"key2" : "value2"
})
}
}
4 changes: 4 additions & 0 deletions examples/actions/local_command/example_script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash

DATA=$(</dev/stdin)
echo "stdin: $DATA, args: $@"
32 changes: 16 additions & 16 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ go 1.24.0

require (
github.com/google/go-cmp v0.7.0
github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/terraform-plugin-framework v1.16.1
github.com/hashicorp/terraform-plugin-framework-validators v0.19.0
github.com/hashicorp/terraform-plugin-go v0.29.0
github.com/hashicorp/terraform-plugin-log v0.9.0
github.com/hashicorp/terraform-plugin-testing v1.13.3
)

Expand All @@ -26,37 +28,35 @@ require (
github.com/hashicorp/go-plugin v1.7.0 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/go-uuid v1.0.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/hashicorp/hc-install v0.9.2 // indirect
github.com/hashicorp/hcl/v2 v2.23.0 // indirect
github.com/hashicorp/hcl/v2 v2.24.0 // indirect
github.com/hashicorp/logutils v1.0.0 // indirect
github.com/hashicorp/terraform-exec v0.23.0 // indirect
github.com/hashicorp/terraform-json v0.25.0 // indirect
github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.37.0 // indirect
github.com/hashicorp/terraform-exec v0.24.0 // indirect
github.com/hashicorp/terraform-json v0.27.2 // indirect
github.com/hashicorp/terraform-plugin-sdk/v2 v2.38.1 // indirect
github.com/hashicorp/terraform-registry-address v0.4.0 // indirect
github.com/hashicorp/terraform-svchost v0.1.1 // indirect
github.com/hashicorp/yamux v0.1.2 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/oklog/run v1.1.0 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/zclconf/go-cty v1.16.3 // indirect
golang.org/x/crypto v0.41.0 // indirect
golang.org/x/mod v0.26.0 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
golang.org/x/tools v0.35.0 // indirect
github.com/zclconf/go-cty v1.17.0 // indirect
golang.org/x/crypto v0.43.0 // indirect
golang.org/x/mod v0.28.0 // indirect
golang.org/x/net v0.45.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.37.0 // indirect
golang.org/x/text v0.30.0 // indirect
golang.org/x/tools v0.37.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
google.golang.org/grpc v1.75.1 // indirect
Expand Down
Loading
Loading