Why does a policy rule run over recorded infrastructure state catch violations a plan-time rule never will?
answer
- look at what the input document contains
- a plan is a delta, not a census
- untouched resources appear in no plan
- state and inventory list what exists
basics
~20 sA plan only contains the resources a change touches, so anything nobody is editing never appears in it. Running the same rule over recorded state or a cloud inventory judges every resource that exists, changed or not.
solid answer
~40 sA plan document is a description of one proposed change: it lists the resources being created, updated, replaced or destroyed and nothing else. A rule fed that document can only ever judge what somebody happened to touch. If a database was created three years ago on an engine version that has since gone end-of-support, and no one has edited that resource since, it will never appear in any plan, so no plan-time run will ever evaluate it. Re-expressing the same rule over the recorded state file, or over an inventory export from the provider, changes the input to `everything that currently exists` — so the untouched population becomes visible. That is the whole reason teams run both: the plan check covers the change, the state check covers the estate.
go deeper
Be ready to say what a plan document actually contains — only the resources this change touches — and therefore what a rule reading it can never see. Naming one example, such as an untouched end-of-support engine, is enough here.
An interviewer expects you to distinguish the three inputs precisely: a plan is a delta, state is what this codebase manages, an inventory export is what the account holds. Say what each one misses.
Show that you know the state run is scheduled rather than change-triggered, produces findings rather than a pass or fail, and needs a routing and closure workflow behind it before it is worth switching on.
Own the argument that plan gates and state scans are different controls with different reach, and that measuring coverage as 'percentage of pipelines with the gate enabled' hides an estate nobody has ever evaluated.
## Two different documents A policy engine does not look at your infrastructure. It looks at a **document** describing your infrastructure, and everything the rule can decide is bounded by what that document contains. **The plan document** is a description of a single proposed change. For each resource involved it carries an address, a type, the action being taken (create, update, replace, destroy, or no-op) and the attribute values the resource will have afterwards. Crucially, a resource that the change does not touch is **not in the document at all**. The plan is a delta, not a census. **The recorded state** is the opposite shape. It is a record of every resource this codebase currently manages, with the attribute values each of them actually has. There is no change and no action in it, because nothing is being proposed — it is a snapshot of what is. **An inventory export** from the cloud provider is wider still: it lists resources in the account regardless of who created them or whether any codebase manages them. Resources created by hand, by another team's codebase, or by a tool that predates your pipeline appear here and appear nowhere else. ## The coverage gap this exposes If every rule you own runs only against plans, the set of resources you have ever actually evaluated is exactly the set somebody has changed since you turned the rules on. Everything else has been silently excluded. Two situations make this concrete: 1. **A resource nobody is changing.** A production database sitting on an engine version that has since gone end-of-support is a real risk — it stops receiving patches — but nothing about it is being deployed. It generates no plan, so it triggers no evaluation. It can stay invisible indefinitely, precisely because it is stable. 2. **A rule you added after the fact.** You write a new rule today. It applies to hundreds of existing resources, but it will only ever fire on the ones that happen to come up in a future change. The rest are grandfathered by accident, not by decision. Re-expressing the rule so it reads state or inventory closes both gaps in one move: the input becomes the population rather than the delta. ## What this looks like in practice A state-or-inventory run is normally **scheduled** rather than triggered by a change — nightly or hourly — because there is no change event to hang it on. Its output is not a pass or fail on somebody's pipeline; it is a set of findings about resources that already exist and are already running. Nothing is being deployed, so there is nothing to refuse. The finding lands in a queue and the response is a human workflow: annotate it, ticket it, fix it forward, or re-run the rule to show it is gone. ## Where each source stops - **State** covers what this codebase manages, and only that. A resource somebody clicked into existence in the console is not in your state file, so a state-only scan will miss it entirely. - **Inventory** covers the account, so it sees the hand-made resources too — often the worst offenders, because they never passed through any pipeline. But it is provider-shaped rather than code-shaped, so the addresses in the findings do not map neatly back onto modules and repositories, which makes routing harder. Most mature setups read both, and treat a resource that appears in inventory but not in state as a finding in its own right. ## The thing to say in an interview The plan gate and the state scan are not two implementations of the same control. The plan gate is the only one that can act **before the resource exists**, and it gives feedback inside the author's own change. The state scan is the only one whose input includes the resources nobody is touching, which is where long-lived risk accumulates. Keeping only the first gives you a green pipeline over an estate you have never examined; keeping only the second means every violation is discovered after it is already running.
- Give a concrete violation a plan-time rule structurally cannot find.A production database on an engine version that went end-of-support after it was provisioned. Nobody has edited the resource, so it appears in no plan and no plan-time run ever evaluates it. The same applies to any rule written after a resource was created: it only fires if that resource happens to come up in a future change.
- If the state scan covers everything, why keep the plan-time check at all?Because the state scan runs after the resource exists. Its finding arrives when the thing is already deployed and serving traffic, so closing it needs a ticket, an owner and a maintenance window. The plan check acts while the change is still a proposal and gives the author feedback inside their own change, where fixing it costs an edit.
- Does a resource have to be in the state file to be scanned?No. State covers only what this codebase manages. An inventory export from the provider also covers resources created by hand or by another codebase — often the ones with the worst findings, because they never passed through a pipeline. A resource present in inventory but absent from state is itself worth flagging.
A plan is the delivery note for today's shipment. State and inventory are the warehouse stocktake. Reading only delivery notes never tells you what has been sitting on the shelf for three years.
saying these in an interview costs you the question
- Believes a plan document lists the whole estate
- Treats a green pipeline as proof the estate is clean
- Assumes every resource eventually shows up in some plan
- Confuses state coverage with full account inventory coverage