Terraform计划声明审阅
审阅Terraform计划有序动作、deposed副本、漂移与输出变更,按来源敏感和未知标记递归处理值。
- 1添加输入
- 2调整设置
- 3获取结果
工具输入和文件在当前浏览器处理,不会上传。
开始之前
分享长计划变更表前,保留替换动作顺序与快照标志,遮盖已标敏感值,并省略无关原始计划章节。
如何使用
- 粘贴terraform show -json导出或选择其JSON文件。
- 检查动作顺序、deposed身份、漂移/输出章节和来源mask指针。
- 下载完整遮盖JSON/CSV;需要省略章节时另行私密保留原plan。
支持范围与限制
一个UTF-8文件/粘贴5MiB;资源、漂移、输出变更分别10000条,JSON值100000、深度64;完整下载20MiB。预算共同生效,失败不给部分报告。
要求format_version1.x与resource_changes,不支持仅state JSON、HCL或二进制plan。仅no-op/read/create/update/delete/delete→create/create→delete七种动作;非空deferred_changes和其他动作拒绝。address+deposed区分副本,同地址不同deposed保留。
before/after区分缺失/null/存在。sensitive true子树为redacted-sensitive,after_unknown true为unknown,可包含partial after中缺失的声明字段;数组mask需形状一致。完整RFC6901 true-mask指针;缺可选mask表示无声明,不是自动识别。
保留支持声明的原数字token、replace_paths、previous_address、index、action_reason和importing。原variables/planned_values/prior_state/configuration及未审查顶层字段值不导出;未知resource/change字段仅列名称。
未标敏感值、地址、导入ID仍可能私密。标志/动作只是快照,不表示apply成功、安全或实际影响。预览200行/每格2000字符;报告超过20000字符时复制是明确预览,JSON/CSV完整下载。不运行Terraform/provider/HCL命令或请求。
操作示例
示例输入
{"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}}}示例参数
{"secondary":"","params":{"spreadsheetSafe":true}}示例输出
{"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."}出现问题时
重新导出完整受支持1.x计划,修正重复address+deposed、mask、动作或JSON;新动作/deferred语义用对应工作流,失败/取消后重跑合法来源。
常见问题
为什么替换会计入删除?
保留两条有序create/delete动作,区分delete→create与create→delete。动作计数只针对resource_changes,漂移/输出另列。
结果已经完全脱敏吗?
没有。只按来源敏感true标记遮盖,未标值、地址和导入ID可能私密;省略顶层字段未审查,不是安全认证。
unknown表示null吗?
不同:真实null有null presence,缺失为absent,unknown true使用明确标记,缺mask为无声明。