Mobile, Cloud & DevOps Tools

Terraform Plan Visualizer

Read terraform show -json plan output and see every resource change grouped by action and module, with replacements and deletions highlighted, attribute-level diffs and sensitive values kept masked.

  • Change summary by action
  • Attribute diffs
  • Risk flags
Runs in your browser

Everything you paste, type or drop is processed in this browser tab. It is not uploaded, logged, stored or sent to analytics.

Terraform plan workspace

1 Your plan

Examples:

Save a plan with terraform plan -out=tfplan, then run terraform show -json tfplan > plan.json. Up to 20 MB. The text output of terraform plan cannot be read.

Drop plan.json, or (up to 20 MB).

2 What the plan will do

Paste plan JSON or load an example, then choose Visualise plan.

What the Terraform Plan Visualizer does

This viewer reads the JSON form of a saved Terraform plan and shows every resource change grouped by action - create, update in place, replace and destroy - with the attribute-level differences, the attributes that force a replacement, and the values Terraform marks as sensitive kept masked. Destroys and replacements are listed first, because they are the changes that lose data or cause downtime.

The plan is parsed in your browser. Nothing is uploaded, and no Terraform command is run: the tool only reads what terraform show -json already printed.

How to use it

  1. Save a plan with terraform plan -out=tfplan, then run terraform show -json tfplan > plan.json.
  2. Paste the JSON or drop plan.json onto the page, then choose Visualise plan.
  3. Read the headline, which uses the same arithmetic as Terraform's own Plan line, then the findings: problems are destroys or replacements of resources whose type suggests they hold data.
  4. Open a resource under Attribute changes to see each changed attribute, what it was, what it will be, and whether it forces replacement.
  5. Copy the Markdown summary into a pull request, or download the CSV or the masked JSON.

Reading the results

Replace (destroy, then create) means the old object is removed before its successor exists, which usually means downtime. Replace (create, then destroy) comes from create_before_destroy and is gentler, but both give the resource a new identity.

(known after apply) means the value is not decided until the provider creates or changes the object - an ID, an ARN, a public IP. A change to it is expected, not a warning.

A resource in Destroy with the reason delete_because_no_resource_config was removed from your configuration; one with a deposed key is an old object left over from an earlier failed replacement.

The data-holding label is an A2Z heuristic based on the resource type name (database, bucket, disk, volume, key, secret and similar). It is a prompt to check backups, not a statement about what the resource contains.

Worked example: a plan with a replacement and a destroy

The example plan has six resource changes. aws_s3_bucket.assets is a no-op and is left out. aws_instance.web has actions delete then create because its ami changes and replace_paths names ami, so it is one replacement. aws_security_group.web and module.db.aws_db_instance.main are updates, aws_s3_bucket.old_reports is a destroy and aws_cloudwatch_log_group.app is a create.

Terraform counts a replacement as both an add and a destroy, so the headline is 1 create + 1 replacement = 2 to add, 2 to change, and 1 destroy + 1 replacement = 2 to destroy - the same figures terraform plan would print.

Two problems are reported: the bucket destroy (the type name contains bucket) and the instance replacement, which happens destroy-first and is forced by ami. The database password change appears as (sensitive value) on both sides, and the output web_ip becomes (known after apply) because the new instance has no IP yet.

Why the JSON plan rather than the text output

The text printed by terraform plan is meant for people and its format changes between versions. The JSON representation is documented by HashiCorp, carries a format_version, and includes the machine-readable pieces this viewer needs: the actions list for each resource, before and after values, after_unknown, the sensitivity maps, replace_paths and action_reason.

The JSON plan contains sensitive values in plain text, even though Terraform hides them in its text output. This viewer masks them before display and in its downloads, but the plan file itself should still be handled like a secret.

Limitations: what the result does not prove

  • It shows what the plan says, not what the provider will actually do. An apply can still fail, and changes made outside Terraform after the plan was saved are not visible.
  • Only attributes present in the plan are compared. Providers that report whole nested blocks as unknown show them as one (known after apply) row.
  • The data-holding flag is a type-name heuristic and will miss custom or unusually named resources; read every destroy, not only the flagged ones.
  • It does not read Terraform state, HCL configuration or the text output of terraform plan.

Privacy: where your data goes

Everything you paste, type or drop is processed in this browser tab. It is not uploaded, logged, stored or sent to analytics. Session recording and tag-manager scripts are switched off on this page.

Standards and sources

Frequently asked questions

How do I get the JSON version of a Terraform plan?

Run terraform plan -out=tfplan to save a binary plan file, then terraform show -json tfplan > plan.json. Running terraform show -json without a plan file prints state instead, which this viewer will recognise and refuse.

Why does Terraform count a replacement as both an add and a destroy?

Because it is one: the existing object is destroyed and a new one is created with a new ID. The Plan line in Terraform's output counts it in both the add and destroy totals, and this viewer's headline does the same so the numbers match.

What does forces replacement mean on an attribute?

The provider cannot change that attribute on the existing object, so Terraform must destroy and recreate it. The plan JSON lists those attributes in replace_paths, and the viewer marks each matching row so you can see which edit triggered the replacement.

Are sensitive values in the plan JSON really hidden?

No. Terraform masks them in its human output, but the JSON plan includes the real values alongside before_sensitive and after_sensitive maps. This viewer uses those maps to mask them on screen and in downloads; the original file still needs protecting.

What is the difference between destroy-then-create and create-before-destroy?

By default Terraform destroys the old object first, which can cause downtime. With lifecycle create_before_destroy it builds the replacement first and removes the old object afterwards, which is gentler but needs names and quotas that allow both to exist briefly.

Why is a resource in my plan that I did not change?

Usually because something changed outside Terraform (listed as drift), a provider upgrade altered a default, or a value it depends on is now unknown. The attribute table shows exactly which values differ, which normally points to the cause.

Can I use this in a CI review?

Yes, by hand: generate plan.json in CI, open it here and paste the Markdown summary into the pull request. The page itself runs no commands and has no API, so it will not block a pipeline automatically.

Last reviewed by the A2Z.Tools team against the sources listed above.

Rate this tool

Was this tool useful? Your feedback helps us improve it.

No ratings yet — be the first to rate this tool.
Your rating (required)
0 / 2000

Please do not include passwords, payment details or other sensitive information.

Your feedback is sent privately to the A2Z.Tools team and will not be posted publicly.