Terraform plan declaration review
Review ordered Terraform plan actions, deposed copies, drift and output changes with recursive supplied sensitive and unknown masks.
- 1Add input
- 2Adjust settings
- 3Get your result
Tool input and files are processed in this browser without being uploaded.
Before you start
Read a long exported plan before sharing its change list. Keep replacement order and snapshot flags explicit while withholding marked values and unrelated raw plan sections.
How to use this tool
- Paste terraform show -json output or select its exported JSON file.
- Review action order,deposed identity,drift/output sections and supplied mask pointers.
- Download complete masked JSON/CSV; retain the original privately when further review needs omitted sections.
Supported inputs and limits
One UTF-8 file/paste5MiB;10,000 resource changes,10,000 drift changes,10,000 output changes,100,000 JSON values,depth64. Complete downloads20MiB; budgets apply together and failures return no partial report.
format_version1.x with resource_changes is required; state-only JSON,HCL and binary plans unsupported. Support only no-op/read/create/update/delete/delete→create/create→delete. Nonempty deferred_changes and other actions reject. Address+deposed identifies copies; the same address with different deposed keys remains.
before/after preserve absent/null/present separately. Sensitive true subtrees become explicit redacted-sensitive markers; after_unknown true becomes unknown, including declared fields absent from partial after. Mask arrays must match shape. RFC6901 true-mask pointers are complete; missing optional masks mean no declaration, not automatic detection.
Retained declared numeric tokens,replace_paths,previous_address,index,action_reason and importing declarations remain exact. Raw variables/planned_values/prior_state/configuration and other unreviewed top-field values are not exported; unknown resource/change field names are listed without their values.
Unmarked values, addresses and import IDs can remain private. Flags/actions describe only the snapshot, not apply success,safety or real impact. Preview200 rows/cell2000; above20,000 report characters, copy is a labelled preview; full JSON/CSV remain complete. No Terraform/provider/HCL command or request runs.
Worked example
Example input
{"format_version":"1.2","terraform_version":"1.13.3","resource_changes":[{"address":"module.x.sample.a[0]","mode":"managed","type":"sample","name":"a","change":{"actions":["delete","create"],"before":{"id":"old","pass":"s1","nested":[1,null]},"after":{"id":null,"pass":"s2","nested":[2,null]},"after_unknown":{"id":true},"before_sensitive":{"pass":true},"after_sensitive":{"pass":true},"replace_paths":[["nested",0]]}},{"address":"sample.b","mode":"managed","type":"sample","name":"b","change":{"actions":["create","delete"],"before":null,"after":{"z":9007199254740993},"after_unknown":{},"before_sensitive":false,"after_sensitive":false}},{"address":"module.x.sample.a[0]","mode":"managed","type":"sample","name":"a","change":{"actions":["delete"],"before":{"id":"old","pass":"s1","nested":[1,null]},"after":null,"after_unknown":false,"before_sensitive":{"pass":true},"after_sensitive":false,"replace_paths":[["nested",0]]},"deposed":"deadbeef"}],"applyable":true,"complete":false,"errored":false,"variables":{"password":{"value":"NEVER_EXPORT_RAW_VARIABLE_SECRET"}},"planned_values":{"secret":"NEVER_EXPORT_PLANNED_SECRET"},"prior_state":{"secret":"NEVER_EXPORT_STATE_SECRET"},"configuration":{"secret":"NEVER_EXPORT_CONFIG_SECRET"},"extra":{"secret":"NEVER_EXPORT_UNKNOWN_SECRET"},"resource_drift":[{"address":"sample.drift","change":{"actions":["delete"],"before":{"id":"drift"},"after":null,"before_sensitive":false,"after_sensitive":false,"after_unknown":false}}],"output_changes":{"public":{"actions":["update"],"before":1,"after":2,"before_sensitive":false,"after_sensitive":false,"after_unknown":false},"private":{"actions":["create"],"before":null,"after":"NEVER_EXPORT_OUTPUT_SECRET","after_sensitive":true,"after_unknown":false}}}Example options
{"secondary":"","params":{"spreadsheetSafe":true}}Example output
{"format":"Terraform-plan1-local-change-declarations","summary":{"formatVersion":"1.2","resourceChanges":3,"driftChanges":1,"outputChanges":2,"create":2,"update":0,"delete":3,"read":0,"noOp":0,"replacements":2,"sensitiveSubtrees":4,"unknownSubtrees":1,"jsonNodes":116,"unreviewedTopFields":5},"flags":{"applyable":true,"complete":false,"errored":false},"sections":[{"name":"resource_changes","values":[{"section":"resource_changes","address":"module.x.sample.a[0]","deposed":null,"actions":["delete","create"],"replacement":true,"replacementOrder":"delete→create","beforePresence":"present","afterPresence":"present","beforeSensitiveStatus":"declared","afterSensitiveStatus":"declared","afterUnknownStatus":"declared","beforeSensitive":["/pass"],"afterSensitive":["/pass"],"afterUnknown":["/id"],"before":{"id":"old","pass":{"$neatboState":"redacted-sensitive"},"nested":[1,null]},"after":{"id":{"$neatboState":"unknown"},"pass":{"$neatboState":"redacted-sensitive"},"nested":[2,null]},"replacePaths":[["nested",0]],"declarations":{"mode":"managed","type":"sample","name":"a"},"unreviewedFields":[],"unreviewedChangeFields":[]},{"section":"resource_changes","address":"sample.b","deposed":null,"actions":["create","delete"],"replacement":true,"replacementOrder":"create→delete","beforePresence":"null","afterPresence":"present","beforeSensitiveStatus":"declared","afterSensitiveStatus":"declared","afterUnknownStatus":"declared","beforeSensitive":[],"afterSensitive":[],"afterUnknown":[],"before":null,"after":{"z":9007199254740993},"replacePaths":[],"declarations":{"mode":"managed","type":"sample","name":"b"},"unreviewedFields":[],"unreviewedChangeFields":[]},{"section":"resource_changes","address":"module.x.sample.a[0]","deposed":"deadbeef","actions":["delete"],"replacement":false,"replacementOrder":null,"beforePresence":"present","afterPresence":"null","beforeSensitiveStatus":"declared","afterSensitiveStatus":"declared","afterUnknownStatus":"declared","beforeSensitive":["/pass"],"afterSensitive":[],"afterUnknown":[],"before":{"id":"old","pass":{"$neatboState":"redacted-sensitive"},"nested":[1,null]},"after":null,"replacePaths":[["nested",0]],"declarations":{"mode":"managed","type":"sample","name":"a","deposed":"deadbeef"},"unreviewedFields":[],"unreviewedChangeFields":[]}]},{"name":"resource_drift","values":[{"section":"resource_drift","address":"sample.drift","deposed":null,"actions":["delete"],"replacement":false,"replacementOrder":null,"beforePresence":"present","afterPresence":"null","beforeSensitiveStatus":"declared","afterSensitiveStatus":"declared","afterUnknownStatus":"declared","beforeSensitive":[],"afterSensitive":[],"afterUnknown":[],"before":{"id":"drift"},"after":null,"replacePaths":[],"declarations":{},"unreviewedFields":[],"unreviewedChangeFields":[]}]},{"name":"output_changes","values":[{"section":"output_changes","address":"public","deposed":null,"actions":["update"],"replacement":false,"replacementOrder":null,"beforePresence":"present","afterPresence":"present","beforeSensitiveStatus":"declared","afterSensitiveStatus":"declared","afterUnknownStatus":"declared","beforeSensitive":[],"afterSensitive":[],"afterUnknown":[],"before":1,"after":2,"replacePaths":[],"declarations":{},"unreviewedFields":[],"unreviewedChangeFields":[]},{"section":"output_changes","address":"private","deposed":null,"actions":["create"],"replacement":false,"replacementOrder":null,"beforePresence":"null","afterPresence":"present","beforeSensitiveStatus":"no-declaration","afterSensitiveStatus":"declared","afterUnknownStatus":"declared","beforeSensitive":[],"afterSensitive":[""],"afterUnknown":[],"before":null,"after":{"$neatboState":"redacted-sensitive"},"replacePaths":[],"declarations":{},"unreviewedFields":[],"unreviewedChangeFields":[]}]}],"omittedTopFields":["variables","planned_values","prior_state","configuration","extra"],"scope":"Actions and flags are snapshot declarations, not apply success/safety/impact. before/after use explicit $neatboState markers for sensitive/unknown/absent subtrees; presence fields distinguish actual null. Only supplied sensitive masks redact; unmarked values/addresses/import IDs may be private. Omitted top fields are not reviewed and their values are never exported. Unknown resource/change fields are named as unreviewed, not exported. Numeric tokens in retained declared values remain exact."}When something does not work
Re-export a complete supported1.x plan; correct duplicate address+deposed identities, masks, actions or JSON. Unsupported deferred/new action semantics require another workflow. Rerun a valid source after failure/cancellation.
Frequently asked questions
Why does a replacement count a delete?
Both ordered create/delete legs remain; replacement order distinguishes delete→create from create→delete. Counts cover resource_changes; drift/output sections are separate.
Is the result fully sanitized?
No. Only supplied sensitive true masks redact. Unmarked values,addresses and import IDs may be private; omitted top fields are unreviewed, not certified safe.
Does unknown mean null?
No. Actual null has null presence; absent has absent presence; true unknown masks use an explicit unknown marker. Missing masks are no-declaration.
Documentation & further reading
Related tools
JSON formatting workspace
Format or minify strict JSON, sort object keys, and encode or decode strings while preserving raw number tokens.
Regex tester
Try a pattern and see what it matches in your text.
Compare text
See what changed, side by side.
HTML formatter
Format HTML indentation so its structure is easier to read.