Documentation · Use it

Where things are stored

WhatWhere it livesWho writes itLosing it costs
MarkersOn the resource: two tags on AWS, one label on KubernetesThe applyThe resource goes invisible and the next plan proposes a duplicate
RecordsThe record store, one per managed resourcechoudoufuFor most resources a slower plan. For a record-backed one, the resource
The cache.terraform/choudoufu-cache.tfstate, on the machine that ranchoudoufuA read

Only the markers say what you own. Records says what a record is, and the cache has its own page.

The record store

# estate.chdf.hcl
estate = "my-estate"

record_store "s3" {
  bucket = "my-records-bucket"
}
BackendWhere it writesArguments
localA directory beside the module, .tofu-records by defaultpath
s3A bucket you already ownbucket (required), bucket_owner, key_prefix, region, allow_insecure
kubernetesSecrets in a namespace you already ownnamespace (default tofu-records-<estate>), and the connection arguments of stock’s kubernetes backend

An estate that declares no record_store gets the local one. Use a bucket or a cluster for anything more than one person shares: on a CI runner the local store is empty on every run, so a record-backed resource is proposed for create again.

A store proves itself before a plan trusts it: the first run writes a sentinel and reads it back through the same listing a plan uses. A store that cannot do that is refused by name, and never reads as an empty estate. A role that may only read can still plan once the sentinel exists.

The local store

One file per record under .tofu-records, readable only by you. Records hold secrets, so gitignore the directory before the first run.

The bucket

One bucket serves any number of estates. Set up a record store bucket has the creating and the policy. An estate writes under three prefixes and nowhere else.

PrefixWhat is there
tofu-records/<estate>/One object per managed resource, and a sentinel
tofu-hints/<estate>/Where the last sweep found things
tofu-outputs/<estate>/The last value of each root output, never a sensitive one

Every write is conditional and nothing is locked.

The cluster

A Kubernetes-only estate keeps its records here and needs no AWS account (Kubernetes). record_store "kubernetes" writes each as an estate-labelled Secret in tofu-records-<estate> or the namespace you name, conditional on the resourceVersion it read, with nothing held. Create the namespace yourself, one per estate (examples/record-store-cluster does, with the Roles): RBAC cannot condition on a label.

live/STORAGE.md has the rest: the exact requests, what destroy leaves behind, an unreachable store, and why receipts stay out.