tfexplain is an open-source CLI for explaining Terraform code, saved Terraform plans, Terraform JSON plans, and piped Terraform plan text.
Author: Vijay Daswani
Company: Build & Automate
Website: buildnautomate.com
Package: bna-tools/tfexplain
Community: Join the Build & Automate Slack
By default, tfexplain is deterministic and dependency-free. It does not call AI services, does not run terraform apply, and does not send code or plan contents anywhere. AI-assisted output is available only when you explicitly pass --ai.
Terraform plans are powerful but noisy. tfexplain turns Terraform code and plan output into readable summaries for engineers, reviewers, and CI/CD pipelines.
- No AI calls unless
--aiis passed. - No
terraform apply. - No cloud changes.
- Plan/code analysis runs locally.
- Secrets are redacted before AI requests.
Install from PyPI:
pip install bna-tfexplainThen run:
tfexplain --helpThe PyPI package name is bna-tfexplain; the CLI command remains tfexplain.
Standalone binary bundles for Linux, macOS, and Windows are attached to GitHub releases.
For local development:
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -e .You can also run it without installing:
PYTHONPATH=src python3 -m tfexplain --helpPipe-friendly local workflow:
terraform plan -no-color | tfexplainRaw plan text gives an action/resource summary. For richer field-level details, use a saved plan or Terraform JSON.
Terragrunt works the same way for a single module:
terragrunt plan -no-color | tfexplainOpenTofu works the same way:
tofu plan -no-color | tfexplainFor richer details with Terragrunt:
terragrunt plan -out=tfplan
terragrunt show -json tfplan | tfexplain plan -For richer details with OpenTofu:
tofu plan -out=tfplan
tofu show -json tfplan | tfexplain plan -terraform plan -out=tfplan
tfexplain plan tfplanYou can also pass Terraform JSON if you prefer to generate it yourself:
terraform show -json tfplan > plan.json
tfexplain plan plan.jsonOr stream Terraform JSON through stdin:
terraform show -json tfplan | tfexplain plan -Passing a saved binary plan file requires terraform, tofu, or terragrunt to be installed because tfexplain converts it locally with show -json.
For OpenTofu and Terragrunt saved plans, tfexplain tries terraform show -json, then tofu show -json, then terragrunt show -json.
Important: terraform plan -out=json, tofu plan -out=json, and terragrunt plan -out=json do not create JSON. They create a saved binary plan file named json. To create JSON, run show -json against a saved plan:
terragrunt plan -out=tfplan
terragrunt show -json tfplan > plan.json
tfexplain plan plan.jsonThis also works:
terraform plan -out=tfplan
terraform show -json tfplan | tfexplain plan -Useful options:
tfexplain plan plan.json --format markdown --output summary.md
tfexplain plan tfplan --group-by risk --show-fields
tfexplain plan tfplan --fail-on delete,replace,hightfexplain code .
tfexplain code ./modules/network --format jsonThe code scanner reports providers, modules, resources, variables, outputs, backend settings, README/examples presence, variable descriptions, validation blocks, and high-attention resource types.
tfexplain explain --code . --plan plan.json --format markdownGenerate a PR-oriented review summary:
tfexplain review --code . --plan tfplan --format markdown
tfexplain review --code . --plan tfplan --format github
tfexplain review --plan plan.json --fail-on delete,replace,highGenerate module documentation:
tfexplain docs . --output TERRAFORM.md
tfexplain docs . --format jsonGenerate a lightweight graph:
tfexplain graph . --format text
tfexplain graph . --format ascii
tfexplain graph . --format mermaid
tfexplain graph . --format dotCreate a local config file:
tfexplain init
tfexplain init --forceSample Terraform code and plan fixtures live in samples/.
tfexplain code samples/terraform-code/aws-webapp
tfexplain code samples/terraform-code/local-pipe-plan
tfexplain plan samples/plans/02-aws-rds-replace.json --show-fields
tfexplain explain --code samples/terraform-code/azurerm-aks --plan samples/plans/03-azurerm-aks-update.json --format markdownTo test the exact pipe workflow with no cloud or Kubernetes provider:
cd samples/terraform-code/local-pipe-plan
terraform init -backend=false
terraform plan -no-color | PYTHONPATH=../../../src python3 -m tfexplainThe plan fixtures cover AWS, AzureRM, Google, Kubernetes, Helm, Cloudflare, Datadog, Random, TLS, and Local providers across create, update, delete, replace, no-op, and module-addressed changes.
To generate real local .tfplan samples:
./samples/tfplans/generate.sh
tfexplain plan samples/tfplans/generated/terraform-data/create.tfplan
tfexplain plan samples/tfplans/generated/terraform-data/update-replace.tfplan --show-fieldsname: tfexplain
on:
pull_request:
jobs:
review:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Install tfexplain
run: |
python -m pip install -e .
- name: Terraform plan
run: |
terraform init
terraform plan -out=tfplan
- name: Generate tfexplain PR comment
run: |
tfexplain review --code . --plan tfplan --format github > tfexplain-review.md
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const body = fs.readFileSync('tfexplain-review.md', 'utf8');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});tfexplain plan <plan.json|tfplan|->
terraform plan -no-color | tfexplain
tfexplain code <directory>
tfexplain explain --code <directory> --plan <plan.json|tfplan|->
tfexplain review --code <directory> --plan <plan.json|tfplan|->
tfexplain docs <directory>
tfexplain graph <directory>
tfexplain init [directory]
tfexplain risk <plan.json|tfplan|->
tfexplain version
AI output appends a generated explanation to the deterministic local analysis.
OpenAI:
export OPENAI_API_KEY=...
tfexplain plan tfplan --ai --provider openai
tfexplain code . --ai --provider openai --model gpt-4o-miniClaude:
export ANTHROPIC_API_KEY=...
tfexplain review --code . --plan tfplan --ai --provider claudeAzure OpenAI:
export AZURE_OPENAI_API_KEY=...
export AZURE_OPENAI_ENDPOINT=https://example.openai.azure.com
tfexplain plan tfplan --ai --provider azure-openai --model <deployment-name>Ollama:
ollama serve
tfexplain code . --ai --provider ollama --model llama3.1Supported providers are openai, claude, azure-openai, and ollama. For JSON output, AI content is added under an ai object.
- GitHub PR comment mode
- Azure DevOps summary output
- More provider-aware risk rules
- HTML report
- SARIF output
- Homebrew install
python3 -m unittest discover -s tests