Skip to content

Repository files navigation

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

OpenTofu works the same way:

tofu plan -no-color | tfexplain

For 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 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 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.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

About

Open-source CLI for explaining Terraform code, plans, and infrastructure changes—with optional AI-powered insights.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages