The local-exec provisioner error occurs when Terraform fails to execute a local command on the machine running Terraform. Common causes include missing commands in PATH, non-zero exit codes, permission issues, or working directory problems. Debugging requires checking command availability, exit codes, and execution environment.
The local-exec provisioner invokes scripts or commands on the local machine that runs Terraform—not on a remote resource. When this provisioner fails, Terraform displays "Error: local-exec provisioner error" with additional context. The error typically stems from one of three sources: the specified command doesn't exist in the execution environment's PATH, the command executes but returns a non-zero exit code (indicating failure), or environmental issues like incorrect working directory or permission problems prevent execution. Unlike remote-exec provisioners which connect over SSH or WinRM, local-exec failures happen directly on your workstation or CI/CD runner, making them easier to debug but sometimes harder to diagnose in automated environments like Terraform Cloud.
First, manually run the exact command from your terminal to ensure it exists and works:
# Test the command from your shell
which your-command
# or
your-command --versionIf the command doesn't exist, you need to install it or update your PATH. For Terraform Cloud or CI/CD, ensure the command is installed in that environment (not just your local machine).
Use on_failure = continue temporarily to see what the command outputs, then check the exit code:
provisioner "local-exec" {
command = "your-command"
on_failure = continue
}Then run:
terraform apply
your-command; echo "Exit code: $?"If the exit code is non-zero, the command is failing. Verify it succeeds independently before adding to Terraform.
If using working_dir, ensure that directory exists:
provisioner "local-exec" {
working_dir = "/path/to/directory"
command = "your-command"
}Test this:
ls -la /path/to/directory
cd /path/to/directory && your-commandUse absolute paths instead of relative paths to avoid confusion about current working directory.
Specify the full path to the command or script:
provisioner "local-exec" {
command = "/usr/bin/bash /absolute/path/to/script.sh"
}On Windows, use full paths:
provisioner "local-exec" {
command = "powershell -Command C:\\path\\to\\script.ps1"
interpreter = ["powershell", "-Command"]
}This prevents PATH resolution issues, especially in CI/CD environments.
Pass required environment variables directly to the provisioner:
provisioner "local-exec" {
command = "deploy.sh"
environment = {
AWS_REGION = var.aws_region
APP_ENV = "production"
}
}Verify the command runs with these variables in your shell:
export AWS_REGION=us-east-1
export APP_ENV=production
./deploy.shTerraform Cloud/Enterprise runs provisioners in a sandboxed environment with a limited PATH. If using local-exec in Terraform Cloud:
1. Use absolute paths (e.g., /usr/bin/aws instead of just aws)
2. Use the built-in interpreter option to call a shell explicitly
3. Consider pre-installing tools via a cloud init or provider setup
4. Check the Terraform Cloud logs for actual error messages
provisioner "local-exec" {
command = "/usr/local/bin/aws s3 ls"
interpreter = ["/bin/bash", "-c"]
}Set TF_LOG to DEBUG for detailed output:
export TF_LOG=DEBUG
terraform apply 2>&1 | grep -A 10 "local-exec"The logs will show the exact command being executed and any error output. This is especially helpful in CI/CD pipelines.
Provisioner Best Practices
While local-exec is useful for post-apply hooks, HashiCorp recommends avoiding provisioners when possible. Provisioners are harder to debug, can make infrastructure less reproducible, and introduce dependencies on the local execution environment. Consider these alternatives:
- null_resource with triggers: Use null_resource for orchestration without creating actual resources
- User data scripts: For cloud resources, use cloud-init or user data scripts instead
- Configuration management: Use dedicated tools like Ansible, Chef, or Puppet
- Cloud functions/lambdas: Trigger post-deployment logic via cloud services
Cross-Platform Compatibility
Commands that work on macOS/Linux may fail on Windows due to path separators and shell differences. Always test on the target platform or use the interpreter option to specify an explicit shell.
Terraform Cloud Limitations
In Terraform Cloud, the execution environment is restricted and may not have the same tools or PATH as your local machine. Always test your provisioners locally before running in Terraform Cloud, and prefer tools that are pre-installed in the TFC runner environment.
Error: Error installing helm release: cannot re-use a name that is still in use
How to fix "release name in use" error in Terraform with Helm
Error: Error creating GKE Cluster: BadRequest
BadRequest error creating GKE cluster in Terraform
Error: External program failed to produce valid JSON
External program failed to produce valid JSON
Error: Unsupported argument in child module call
How to fix "Unsupported argument in child module call" in Terraform
Error: network is unreachable
How to fix "network is unreachable" in Terraform