tfexplain
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.
Demo
Why tfexplain?
Terraform plans are powerful but noisy. tfexplain turns Terraform code and plan output into readable summaries for engineers, reviewers, and CI/CD pipelines.
Safety & Privacy
- No AI calls unless
--aiis passed. - No
terraform apply. - No cloud changes.
- Plan/code analysis runs locally.
- Secrets are redacted before AI requests.
Install for Development
Install from PyPI:
pip install bna-tfexplain
Then run:
tfexplain --help
The 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 --help
Explain a Terraform Plan
Pipe-friendly local workflow:
terraform plan -no-color | tfexplain
Raw 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 | tfexplain
For richer details with Terragrunt:
terragrunt plan -out=tfplan
terragrunt show -json tfplan | tfexplain plan -
terraform plan -out=tfplan
tfexplain plan tfplan
You can also pass Terraform JSON if you prefer to generate it yourself:
terraform show -json tfplan > plan.json
tfexplain plan plan.json
Or stream Terraform JSON through stdin:
terraform show -json tfplan | tfexplain plan -
Passing a saved binary plan file requires the terraform executable to be installed because tfexplain converts it locally with terraform show -json.
This 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,high
Explain Terraform Code
tfexplain code .
tfexplain code ./modules/network --format json
The code scanner reports providers, modules, resources, variables, outputs, backend settings, README/examples presence, variable descriptions, validation blocks, and high-attention resource types.
Explain Code and Plan Together
tfexplain explain --code . --plan plan.json --format markdown
Review, Docs, Graph, and Init
Generate 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,high
Generate module documentation:
tfexplain docs . --output TERRAFORM.md
tfexplain docs . --format json
Generate a lightweight graph:
tfexplain graph . --format text
tfexplain graph . --format ascii
tfexplain graph . --format mermaid
tfexplain graph . --format dot
Create a local config file:
tfexplain init
tfexplain init --force
Samples
Sample 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 markdown
To 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 tfexplain
The 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-fields
GitHub Action Example
name: 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,
});
Commands
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 Mode
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-mini
Claude:
export ANTHROPIC_API_KEY=...
tfexplain review --code . --plan tfplan --ai --provider claude
Azure 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.1
Supported providers are openai, claude, azure-openai, and ollama. For JSON output, AI content is added under an ai object.
Roadmap
- GitHub PR comment mode
- Azure DevOps summary output
- More provider-aware risk rules
- HTML report
- SARIF output
- Homebrew install
Test
python3 -m unittest discover -s tests
Metadata
Release files for bna-tfexplain 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| bna_tfexplain-0.1.3.tar.gz | 32.2 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bna_tfexplain-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.5 kB
Release files / bna_tfexplain-0.1.3.tar.gz
| Download URL | bna_tfexplain-0.1.3.tar.gz |
|---|---|
| Size | 32.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f4391ce064a862a17adec1926132b3c41d3679fb18829c81209042ada5e21aca
|
|
BLAKE2b-256 checksum How to use checksums |
bc53fcbec2615b7b31fd4bf7c2e38efaa8a314a93133291caeff6a0d40241e48
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.
Transparency logRelease files / bna_tfexplain-0.1.3-py3-none-any.whl
| Download URL | bna_tfexplain-0.1.3-py3-none-any.whl |
|---|---|
| Size | 30.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f5040bce7e85ac000800aa6ce9f19d5e30b3da4cad2bd6b14c30b2b837ba63b6
|
|
BLAKE2b-256 checksum How to use checksums |
83c2ca6967ad4fe6afa8a887652d85030da4fe1b14cfe7104ee2d3ed65209d74
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.
Transparency logSecurity for bna-tfexplain 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for bna_tfexplain-0.1.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 5, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.