Ansible keeps no state file, while Terraform and Pulumi record one. How does a tool with no recorded state decide what to do on each run, and what does each approach trade away?
answer
- where does the tool keep its memory
- re-derive from the target every run
- idempotent per step, not per diff
- the one thing it can never notice
- removal must be declared, not implied
basics
~20 sA stateless tool re-derives reality from the target on every run: each step reads the current condition and acts only if it differs. It has nothing to lose, lock or leak, but it cannot notice that something you deleted from the code should be removed.
solid answer
~50 sThere are really three answers to "where does the tool remember things". A tool with a client-side record, like Terraform or Pulumi, stores the mapping itself. A hosted service like CloudFormation keeps the equivalent record server-side, per stack, so you never hold a file. A tool like Ansible keeps nothing at all: on every run each step inspects the target — is this package installed, does this file already have these contents — and converges only what differs. Idempotency there is a property of each step, not of a diff against history. The trade is deletion tracking. Because a stateless run has no memory of what previous runs created, removing a step from the code simply means it stops being enforced; if you want something gone you must declare it absent explicitly. In exchange there is no record to corrupt, lock, back up, or leak secrets from, and no drift between the record and reality — because the target is re-read every time.
go deeper
Know that some tools write a record of what they created and others check the target's current condition on every run. Be able to say which family Ansible and Terraform belong to.
Explain that per-step checks give idempotency without any history, and name the consequence: a stateless tool cannot infer that something removed from the code should be deleted. Removal must be declared explicitly.
Weigh the trades for a real estate — recoverability and preview quality against having no artefact to lock, back up or leak — and describe how you retire configuration safely on a fleet with no recorded inventory.
Own the mixed-estate question: which layers deserve a recorded inventory, who holds it, and what the organisation accepts when part of the platform is managed by tools whose memory lives only in the target.
## Three places the memory can live Every infrastructure tool has to answer "what already exists". They answer it in one of three ways, and almost every design difference follows from the choice. **Client-side record.** Terraform and Pulumi write a state record that they own — the mapping from configuration addresses to real object identifiers, plus recorded attributes and dependency edges. The tool reads it, refreshes it against the provider, diffs, acts, and writes it back. **Server-side record.** CloudFormation keeps the same information, but the service holds it. A stack is a server-side object that knows every logical id in the template, the physical id it corresponds to, and the deployment history. You never have a file to store, back up or lock; you also cannot inspect or repair the record with ordinary tools, and it exists only inside that one cloud. **No record at all.** Ansible re-derives everything from the host on each run. A step that ensures a package is present asks the package manager whether it is already there. A step that ensures a file has certain contents compares them and rewrites only on a difference. Reported "changed" versus "ok" is the outcome of that comparison, not of a diff against a stored history. Continuously reconciling controllers sit at the same end of the spectrum for a different reason: the live objects in the cluster *are* the record, so the controller compares declared spec to observed reality on every pass. ## What the stateless design gives up **Deletion tracking.** This is the one irreducible loss, and it is the answer interviewers are listening for. To know that something should be removed you must know it once existed, and that is exactly what a stateless tool does not know. Delete a task from a playbook and the effect is that the task stops being enforced — the package it installed stays installed forever. Removal has to be expressed positively: you write a step that declares the thing absent, keep it around long enough for every host to run it, and only then delete it. The mental model is "I enforce a set of assertions about a host", not "I own an inventory of objects". **Ownership.** With no record there is nothing that says "this file is mine". Two teams can converge the same host with contradictory assertions and the last run simply wins. A record at least makes overlapping ownership visible as a conflict. **Cheap previews.** A diff against a record can be computed largely from stored data. A stateless tool has to reach out and inspect the real target to predict anything, so previews cost the same connections as a real run and are only as good as each step's dry-run support. ## What it gets in return **Nothing to lose or corrupt.** There is no file to accidentally delete, no lock to go stale, no back-up policy to get wrong, no divergence between two copies of the record. Recovery from a botched run is another run. **No stale beliefs.** A recorded attribute can disagree with reality; re-deriving cannot. Drift between the record and the world is a category of bug that simply does not exist here — every run starts from what is actually there. **Nothing to leak.** A record accumulates attribute values, including sensitive ones. A tool that stores nothing between runs has no such artefact to protect (its secrets problem moves to how credentials reach the run, not to what is written down afterwards). ## Why the split is not arbitrary The two families historically target different problems. Configuration management converges long-lived machines whose contents are largely enumerable on demand: you can ask a host what packages it has. Provisioning tools create objects in a provider where the mapping from your names to their identifiers is *not* enumerable — an account full of subnets cannot tell you which configuration made which. The less discoverable the ownership, the more a record earns its cost. ## Answering well A strong answer names the three designs, states the deletion-tracking trade in one sentence, and resists the claim that stateless means "non-declarative" or "not idempotent" — a stateless tool is usually both. It is simply idempotent step by step rather than by comparison against a remembered inventory.
- If a stateless tool cannot notice removals, how do teams actually retire configuration safely?By making removal an explicit assertion. You replace the step that creates the thing with one that declares it absent, let every target run at least once — which is why fleets are run on a schedule, not only on change — and delete the assertion afterwards. Teams that skip the intermediate step accumulate cruft: packages and files nobody has enforced for years but nothing has ever removed.
- Does keeping the record server-side, as CloudFormation does, remove the concurrency problem?It relocates it rather than removing it. The service serialises operations on a stack itself, so you cannot corrupt the record with two concurrent updates — a second update is simply rejected while one is in progress. What you lose is the ability to inspect or repair that record with your own tooling, and the record is only as available as the service holding it.
- Is a tool without recorded state less declarative?No. Declarative describes the input — you state the desired condition rather than the steps — and stateless tools are usually written that way. What the missing record removes is history, not intent: the tool still converges toward what you declared, it just cannot infer anything about what you stopped declaring.
saying these in an interview costs you the question
- Ansible has no state, so it isn't idempotent
- Stateless tools rediscover and delete what you removed
- CloudFormation keeps no record because there's no file
- Without state the tool re-applies everything every run
- A state file is always the better design