Safeguard
Security Guides•

Are Terraform provisioners safe? Risks of local-exec and remote-exec

HashiCorp calls provisioners a last resort. Why local-exec and remote-exec add risk, what SSH host key checking does by default, and what to use instead.

Safeguard Security Team
4 min read

Provisioners are not unsafe by themselves, but HashiCorp advises exhausting all alternatives first. They run commands outside Terraform's model, usually need network access and credentials to your servers, and add risk that is hard to review in a plan.

What provisioners are

A provisioner is a block inside a resource that runs an action after the resource is created. There are three built in types: file copies files to the new resource, local-exec runs an executable on the machine running Terraform, and remote-exec runs one on the remote resource.

Why the documentation warns against them

The Terraform documentation gives two reasons. Terraform cannot predictably model provisioner behavior, so a plan does not show what a script will do. And most provisioners require direct network access to your servers and credentials to install software, which the page says introduces complexity and potential security issues.

For a reviewer, that means a short local-exec command is invisible in the plan output. The security question moves from "what resources change" to "what does this script do, with which credentials, on which machine".

The SSH host key default

For SSH connections, the documentation states that host key validation is disabled by default, because SSH is most often used with newly created machines. If that is not acceptable, you can set up your own key distribution and set the host_key argument to verify a specific key or signing CA.

Risk table

ProvisionerRuns whereMain review concern
local-execTerraform runnerShell commands with the runner's credentials, and input values that reach the command
remote-execTarget serverNetwork path, login credentials, unverified host key by default
fileTarget serverWhat is copied, and where the secrets come from

Safer patterns

  1. Check whether the provider offers a first class way to do the task.
  2. Bake software into a machine image so there is nothing to run after creation.
  3. Use configuration management or cloud init mechanisms for post creation setup.
  4. If you must use a provisioner, set host_key and keep scripts in version control.
  5. Use ephemeral values in provisioner and connection blocks where your Terraform version supports it (1.10 and later), so credentials are not kept in state.

What to flag in review

  • Any new provisioner block, with a note on why no alternative works.
  • Commands built from variables or data source output.
  • Connection blocks with passwords or private keys.
  • on_failure = continue, which lets a failed script go unnoticed.

Try it yourself

Click through it at your own pace, or open it full screen. See how a change can be held for review, and consider adding any new provisioner block to your own review triggers.

Quick check

Is local-exec more dangerous than remote-exec?

They carry different risks. local-exec uses the runner's credentials and network position, while remote-exec uses a login to the target.

Do provisioners show up in terraform plan?

The block is part of the configuration, but the plan cannot predict what the command will do.

Is there a built in way to avoid provisioners?

Often yes: provider arguments, machine images or configuration management, depending on the task.

Safeguard offers SBOM and dependency scanning and policy gates that can block a pull request on findings, and you can try a free scan at gold.safeguard.sh/scan.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.