Skip to main content

tfexplain

Version License Terraform

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

tfexplain terminal 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 --ai is 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

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bna_tfexplain-0.1.3.tar.gz (32.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bna_tfexplain-0.1.3-py3-none-any.whl (30.3 kB view details)

Uploaded Python 3

File details

Details for the file bna_tfexplain-0.1.3.tar.gz.

File metadata

  • Download URL: bna_tfexplain-0.1.3.tar.gz
  • Upload date:
  • Size: 32.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bna_tfexplain-0.1.3.tar.gz
Algorithm Hash digest
SHA256 f4391ce064a862a17adec1926132b3c41d3679fb18829c81209042ada5e21aca
MD5 dada2a50271343062b72dfccf92d6e91
BLAKE2b-256 bc53fcbec2615b7b31fd4bf7c2e38efaa8a314a93133291caeff6a0d40241e48

See more details on using hashes here.

Provenance

The following attestation bundles were made for bna_tfexplain-0.1.3.tar.gz:

Publisher: release.yml on Vijaydaswani/tfexplain

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file bna_tfexplain-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: bna_tfexplain-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 30.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for bna_tfexplain-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 f5040bce7e85ac000800aa6ce9f19d5e30b3da4cad2bd6b14c30b2b837ba63b6
MD5 1c8053deebc9eaf7b2a85e0d055549c4
BLAKE2b-256 83c2ca6967ad4fe6afa8a887652d85030da4fe1b14cfe7104ee2d3ed65209d74

See more details on using hashes here.

Provenance

The following attestation bundles were made for bna_tfexplain-0.1.3-py3-none-any.whl:

Publisher: release.yml on Vijaydaswani/tfexplain

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 files

0.1.2

2 files

0.1.1

2 files

0.1.0

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page