tf-peek
The Terraform plan reviewer that knows what your team considers dangerous.
Declare your risk model once in peek_config.toml. Get a Markdown review report that escalates what
matters, silences what doesn't, and fails the build when something irreversible is on the table.
Same plan, same command, one peek_config.toml apart. On the left, 12 changes all look alike and the
replaced production database is somewhere below the fold. On the right, 3 critical operations are
hoisted above the summary and 4 routine changes are counted but not detailed.
Why tf-peek
Every other plan renderer shows you what changes. tf-peek renders an opinion about the plan.
- Three tiers, declared per repository —
silent,normal,critical, matched on resource type or on an address regex. No policy DSL, no Rego, no SaaS. - Per-action escalation —
critical_on = ["delete", "replace"]: creating a bucket is routine, deleting one is not. - 🚨 above the fold — critical changes render before the summary, so a destructive operation survives a skim of a 400-line report.
- Silenced, never hidden — silent resources are still counted, so the report never lies by omission.
- Sensitive values masked by default — anything Terraform marks sensitive renders as
(sensitive value)at any nesting depth;--show-sensitiveis an explicit opt-out. - A gate, not just a report —
--fail-on-criticalexits3when a critical operation is on the table, so CI can block the merge. - Deterministic and offline — same plan in, byte-identical report out. No network calls, no state access, no credentials. Safe to run in any pipeline.
Install
uv tool install tf-peek # or: pipx install tf-peek or: pip install tf-peek
Quick start
terraform plan -out=tfplan
terraform show -json tfplan > plan.json
tf-peek plan.json --output report.md
Or pipe the plan straight in:
terraform show -json tfplan | tf-peek -
Declare your risk model
tf-peek reads peek_config.toml from the current working directory, or the file given to
--config:
# Counted in the summary, never detailed.
[[resources]]
match_type = "null_resource"
tier = "silent"
# Deleting or replacing this is a 🚨 event — and so is updating it.
[[resources]]
match_type = "google_sql_database_instance"
tier = "critical"
critical_on = ["delete", "replace", "update"]
# Noisy but harmless: title only, no attribute diff.
[[resources]]
match_type = "google_project_iam_member"
tier = "normal"
detail = "summary"
Without a config file every resource is normal — that is the left-hand side of the screenshot
above. The full GCP-flavoured example used for the right-hand side is
config.toml, and the plan it was run
against is examples/demo-plan.json.
Gate CI on critical changes
tf-peek plan.json --fail-on-critical --output report.md
status=$?
if [ "$status" -eq 3 ]; then
echo "Critical change detected — blocking merge"
exit 1
elif [ "$status" -ne 0 ]; then
echo "tf-peek failed to run (exit $status)"
exit "$status"
fi
Exit 3 means the gate fired and the report was still written; exit 1 means the tool itself
failed. Use --fail-on-critical-on delete to fail only on destructive actions.
Documentation
Full documentation lives at looztra.github.io/tf-peek, organised with the Diataxis framework:
| Type | Start here |
|---|---|
| Tutorial | Your first Terraform plan report |
| How-to | Install · Generate a report · Silence noisy resources · Flag critical resources |
| Reference | CLI · Configuration |
| Explanation | Resource tiers |
Contributing
Issues and pull requests are welcome — see CONTRIBUTING.md and the Code of Conduct. Curated tier presets for a provider you know well are the highest-value contribution and need domain knowledge rather than Python.
To report a vulnerability, follow the security policy — never a public issue.
License
Metadata
Release files for tf-peek 1.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tf_peek-1.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / tf_peek-1.3.0-py3-none-any.whl
| Download URL | tf_peek-1.3.0-py3-none-any.whl |
|---|---|
| Size | 24.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b008a1e0dd236912ce30aa9c34d2145da92705fc324e854402a3ab167fcc910b
|
|
BLAKE2b-256 checksum How to use checksums |
c6bd702bb4a7242178b6b36be35e3ae35dd4bc1217d6cfb063fa994587f7c211
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 2, 2026.
Transparency log