Infra Plan Readback

Reads a Terraform or OpenTofu plan back with data-losing destroys and replacements first, so an apply doesn't quietly delete a production database.

StopsHelps prevent terraform apply destroying a production database

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/infra-plan-readback.json

The files land in your project. They're yours to edit.

Usage

infra-plan-readback-usage.tsx
import { InfraPlanReadback } from "@/components/ui/infra-plan-readback"

<InfraPlanReadback plan={PLAN} workspace="prod-eu" onApply={() => new Promise<void>((resolve) => setTimeout(() => (setApplied(true), resolve()), 800))} />

What it catches

  • Destroys and replacements of databases, buckets, volumes and keys, listed first
  • The attribute that forces a replacement (before → after, sensitive values hidden)
  • Destroy-before-create replacements that leave a gap
  • force_destroy and skip_final_snapshot consequences
  • Production workspace, or var.environment saying production when the workspace doesn't

Props

InfraPlanReadback props
PropTypeDefault
plan* (required)

`terraform show -json <planfile>` output, parsed or as text.

unknown—
workspace

Workspace name (`terraform workspace show`) or an environment label.

string—
production

Force production handling on or off. Defaults to reading the workspace name and var.environment.

boolean—
statefulTypes

More resource types that hold data.

string[]—
isStateful

Your own stateful test; overrides the built-in list.

(type: string) => boolean—
onApply

Called on Apply. May return a Promise; shows a pending state and ignores repeat clicks.

() => void | Promise<void>—
messages

Any visible string; `actions` may be partial.

Partial<Omit<InfraPlanMessages, "actions">> & { actions?: Partial<InfraPlanMessages["actions"]> }—

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • Parse errors and unappliable plans use role=alert
  • Data-loss list is a labelled section with a checkbox label per item
  • Workspace confirmation input has a visible label
  • Status uses role=status; sign icons are aria-hidden with the action named in text

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

This is a UX guard rail. Enforce on the server: Protect production state with policy checks (OPA/Sentinel), prevent_destroy and deletion protection, and require reviewed plans in CI.

  • Only as good as the plan JSON; a plan made against stale state or a different workspace isn't detected
  • Stateful detection uses a built-in type list plus your statefulTypes/isStateful
  • The lock is in this UI; terraform apply from a terminal or CI is not affected

What it stops

Helps prevent terraform apply destroying a production database

Also known as

terraform plan · terraform apply · opentofu · iac · infra · aws rds · s3 bucket · devops

Field type

Dependencies

Pairs well with