Skip to content

Conversation

@austinvalle
Copy link
Member

Related Issue

N/A

Description

This PR introduces a new action to the local provider, local_command, which is intended to be a generic way to run an executable on the local machine of whatever system is running Terraform. Generally this action is like an escape hatch and is built in a similar fashion to the local-exec provisioner. (although in it's current form, actions do not have all the necessary features to consider local_command to be a replacement for local-exec)

The local_command is being introduced here, rather than the external provider, because the purpose of the only data source in the external provider is to interact with executables that are purpose-built for Terraform with a documented protocol (must produce valid JSON on STDOUT, must accept a JSON object on STDIN, etc). The local_command is meant to interact with any executable on the local machine, and thus allows the users, for example, to format their own STDIN data + arguments:

action "local_command" "bash_example" {
  config {
    command   = "bash"
    arguments = ["example_script.sh", "arg1", "arg2"]
    # In the external provider, the data is automatically encoded to JSON, here
    # we encode the data using the built-in jsonencode function
    stdin = jsonencode({
      "key1" : "value1"
      "key2" : "value2"
    })
  }
}

This control means that the practitioner can interact with essentially any executable with any data format for input that can be represented in Terraform:

action "local_command" "bash_example" {
  config {
    command   = "bash"
    arguments = ["example_script.sh", "arg1", "arg2"]
    # Send YAML instead
    stdin = yamlencode({
      "key1" : "value1"
      "key2" : "value2"
    })
  }
}

As this is an action, as of today, the user cannot consume any of the STDOUT data produced by the command, so we output that data via a progress message:

 $ 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): 

# <STDOUT from the executable will display here once the command has finished execution>

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

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

Rollback Plan

  • If a change needs to be reverted, we will roll out an update to the code within 7 days.

Changes to Security Controls

No

@austinvalle austinvalle added this to the v2.6.0 milestone Nov 3, 2025
@austinvalle austinvalle requested a review from a team as a code owner November 3, 2025 20:27
SBGoods
SBGoods previously approved these changes Nov 10, 2025
Copy link
Contributor

@SBGoods SBGoods left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@austinvalle austinvalle merged commit 5010019 into main Nov 13, 2025
78 checks passed
@austinvalle austinvalle deleted the av/local-action branch November 13, 2025 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants