live

package
v0.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 24, 2026 License: MPL-2.0 Imports: 0 Imported by: 0

Documentation

Overview

Package stateless implements OpenTofu's stateless mode: a run mode with no authoritative state file, no backend, and no lock. Identity is recovered from the live system on every operation instead of being read from a stored record.

Projections

The state data structure does not disappear; its authority does. A projection is an ephemeral prior-state, built at the start of an operation by reading the live system and discarded once the operation completes. It is fed to the unchanged plan engine in place of a state read and is never persisted. Same shape as a states.State, none of the authority: nothing downstream trusts a projection to be correct, because nothing depends on it surviving past the run that built it.

Contrast with authoritative state, whose test is that a wrong record makes OpenTofu do the wrong thing to the world. A wrong projection costs at most a re-plan.

Admission

A resource type participates in stateless mode only if its identity is recoverable with no memory. Four paths admit a resource, strongest first:

  1. Client-assigned identity: the name is already in the configuration (a bucket name, a role name, a log group name). Nothing to recover.
  2. Marker: the resource carries ownership tags, defined in live/MARKERS.md, and is found by a tag-filtered list call.
  3. Parent-derived: identity is a composite key built from already-admitted parents, such as a route keyed by route table and destination, or an association keyed by subnet and route table.

A resource type with none of these three paths is out of the stateless subset and is rejected by lint before a projection is ever built.

There used to be a fourth, "list and content match: the provider's list protocol enumerates candidates and binding proceeds by content". No such path exists. Nothing in internal/live/discovery binds by content: the Cloud Control leg lists an object, refines it with GetResource, and DISCARDS it when neither carried tags (cloudcontrol.go's ProblemNoTags, an error). The paragraph on foreign resources below says the same thing in the opposite direction - a content match is "surfaced for explicit adoption and never bound automatically" - and the two sat twenty lines apart contradicting each other, with the promise also reaching a user through lint's unadmitted-type refusal.

Enumerability is still a real and separately useful fact about a type: it is what a sweep needs to notice an undeclared object at all. It is not an admission path, because admission is about naming the object this configuration means, and a listing that cannot read a marker names nothing. tools/survey-gen records the enumeration fact under its own label for that reason.

Foreign resources

A live resource of an in-scope type with no admission path binding it to configuration is foreign: unrecognized, unmanaged, and never auto-deleted. Stateless mode reports it for review rather than guessing whether it should be adopted or destroyed. A foreign resource that happens to match a declared-but-unbound resource is a bind candidate, surfaced for explicit adoption and never bound automatically.

Count

count survives stateless mode as cardinality over a fungible set rather than as a positional index. Each instance carries a tofu-slot marker: a stable, opaque identifier assigned once at creation and never reused. Binding N declared instances against M live, owned instances is set matching, not index matching: a deficit creates new slots, a surplus deletes the highest slots. Nothing about identity depends on count.index, which is why count.index is banned from identity-bearing resource arguments while the count = var.enabled ? 1 : 0 idiom keeps working unchanged.

Where the phases land

The projection is built and consumed at three seams in the existing codebase, not in a parallel state system:

  • internal/states/statemgr: Filesystem is the model for a projection manager. A projection manager's Refresh/State builds its snapshot from live reads instead of a file, and Persist writes nothing (or, when a record_store is configured, guided discovery's plan-cost hint - a type roster and a timestamp that no code path reads back as truth; issue #109).
  • Import machinery in internal/tofu: resource identity is merged upstream (opentofu#2854); the same import-by-identity path that backs tofu import is how a projection materializes a states.State for the client-named and parent-derived admission paths.
  • The provider list protocol: the mechanism behind admission path 4 and behind tag-filtered marker discovery. Core-side client support tracks the shape of opentofu#3787 to stay mergeable with upstream.

This package holds the model. Concrete implementations live in its subpackages: lint, identity, discovery, stamp, projection, and the rest. The operator-facing specs are in live/.

Directories

Path Synopsis
Package acceptance is GitHub issue #108's tier: every cohort estate under live/e2e/estates is applied against the floci emulator, its state file is deleted, and the plan rebuilt from ownership markers alone is asserted empty - the definition of done a user can check for themselves, run per cohort as a measurement.
Package acceptance is GitHub issue #108's tier: every cohort estate under live/e2e/estates is applied against the floci emulator, its state file is deleted, and the plan rebuilt from ownership markers alone is asserted empty - the definition of done a user can check for themselves, run per cohort as a measurement.
Package check answers "would this configuration move under live resource markers, and if not, what stops it" using only the configuration: no backend, no state, no cloud reads, and no provider process beyond reading schemas.
Package check answers "would this configuration move under live resource markers, and if not, what stops it" using only the configuration: no backend, no state, no cloud reads, and no provider process beyond reading schemas.
Package cloudcontrol is a client for AWS's Cloud Control API: the transport the registry-backed discovery plane (#40) reads live resources through.
Package cloudcontrol is a client for AWS's Cloud Control API: the transport the registry-backed discovery plane (#40) reads live resources through.
Package dataread is issue #179's pre-resolution data-read phase: provider data sources whose values identity resolution needs, read before resolution runs instead of refused as non-static.
Package dataread is issue #179's pre-resolution data-read phase: provider data sources whose values identity resolution needs, read before resolution runs instead of refused as non-static.
The parent-scoped Cloud Control leg.
The parent-scoped Cloud Control leg.
Package docsref parses and resolves the documentation references the live path's refusals carry.
Package docsref parses and resolves the documentation references the live path's refusals carry.
Package flocitest holds the gate, the fixture paths and the container bookkeeping that the floci integration tests share.
Package flocitest holds the gate, the fixture paths and the container bookkeeping that the floci integration tests share.
Package foreign classifies the live resources an estate does not own, and is the safety property of stateless mode: a live resource nobody claims is surfaced, and is never a deletion candidate.
Package foreign classifies the live resources an estate does not own, and is the safety property of stateless mode: a live resource nobody claims is surfaced, and is never a deletion candidate.
Package harness holds the two registries this repository's numbers live in: what it is driving down (the burndown), and what it believes while it does (the assumptions).
Package harness holds the two registries this repository's numbers live in: what it is driving down (the burndown), and what it believes while it does (the assumptions).
Package identity classifies the identity of every managed resource instance in a configuration, using nothing but the configuration itself.
Package identity classifies the identity of every managed resource instance in a configuration, using nothing but the configuration itself.
Package lifecycle holds five integration tests and nothing else: the lifecycle test itself (P4.1), the guided-discovery hint test (issue #109), the exactness test (P5.1), the crash-mid-apply test (the concurrency taxonomy's crash row, run rather than argued), and the existence-flavor receipt test (RA.6).
Package lifecycle holds five integration tests and nothing else: the lifecycle test itself (P4.1), the guided-discovery hint test (issue #109), the exactness test (P5.1), the crash-mid-apply test (the concurrency taxonomy's crash row, run rather than argued), and the existence-flavor receipt test (RA.6).
Package lint is the stateless-mode subset check: the pass that decides whether a configuration can be planned with no authoritative state at all.
Package lint is the stateless-mode subset check: the pass that decides whether a configuration can be planned with no authoritative state at all.
Package listclient is stateless mode's client for the provider list protocol: the ListResource server-streaming RPC and the list resource schemas that parameterize it.
Package listclient is stateless mode's client for the provider list protocol: the ListResource server-streaming RPC and the list resource schemas that parameterize it.
Package liveimport is the bulk migration path from a state-backed estate to ownership markers (issue #61): read an existing tfstate file once, verify every resource it names against the live system, and - only when the operator says so a second time - stamp this estate's markers onto everything that verified.
Package liveimport is the bulk migration path from a state-backed estate to ownership markers (issue #61): read an existing tfstate file once, verify every resource it names against the live system, and - only when the operator says so a second time - stamp this estate's markers onto everything that verified.
Package markerkey holds the for_each instance key rule that lint and identity both enforce.
Package markerkey holds the for_each instance key rule that lint and identity both enforce.
Package markers is live/MARKERS.md in code: the ownership tag keys, the escaping rule that lets a resource address live in a tag value, and the reading of those tags off a live object.
Package markers is live/MARKERS.md in code: the ownership tag keys, the escaping rule that lets a resource address live in a tag value, and the reading of those tags off a live object.
markerstest
Package markerstest holds the two resource schemas every package that decides "may a marker be written here" has to agree about, so that the packages asserting it do not each rebuild the block and thereby rebuild the disagreement the assertion exists to catch.
Package markerstest holds the two resource schemas every package that decides "may a marker be written here" has to agree about, so that the packages asserting it do not each rebuild the block and thereby rebuild the disagreement the assertion exists to catch.
Package marksafe is the lockstep check behind GitHub issue #240: a cty.Value accessor that panics on a marked value cannot be called in a live package on a value nothing proves is unmarked.
Package marksafe is the lockstep check behind GitHub issue #240: a cty.Value accessor that panics on a marked value cannot be called in a live package on a value nothing proves is unmarked.
Package mdspan rewrites named regions of a committed markdown document in place.
Package mdspan rewrites named regions of a committed markdown document in place.
Package moved carries a configuration's `moved` blocks into the live-marker world, where there is no state entry to rewrite.
Package moved carries a configuration's `moved` blocks into the live-marker world, where there is no state entry to rewrite.
Package mv performs the rename operation stateless mode has instead of `moved` blocks and state surgery: it rewrites the tofu-address ownership marker on one live resource.
Package mv performs the rename operation stateless mode has instead of `moved` blocks and state surgery: it rewrites the tofu-address ownership marker on one live resource.
Package onboard computes the source edit that turns a state-backed module into a live one, from the module's own text and from nothing else.
Package onboard computes the source edit that turns a state-backed module into a live one, from the module's own text and from nothing else.
Package passthrough is the registry of refusals the live path shows a user without having written them.
Package passthrough is the registry of refusals the live path shows a user without having written them.
Package pins holds the provider release the measurement instruments pin, as one constant instead of one per tool.
Package pins holds the provider release the measurement instruments pin, as one constant instead of one per tool.
Package pluginschema reads a provider's schemas by launching its plugin in-process, with no cloud calls and no provider configuration.
Package pluginschema reads a provider's schemas by launching its plugin in-process, with no cloud calls and no provider configuration.
Package policy is GitHub issue #67's ownership-policy matrix, given a settled shape: a verb per quadrant (declared-in-source x carries-the-tag), the tag those quadrants read, and the delete quadrant's safety rails.
Package policy is GitHub issue #67's ownership-policy matrix, given a settled shape: a verb per quadrant (declared-in-source x carries-the-tag), the tag those quadrants read, and the delete quadrant's safety rails.
Package projection materializes an ephemeral prior state by reading the live system.
Package projection materializes an ephemeral prior state by reading the live system.
Package providerscope resolves a resource's true root-level provider configuration address by walking every ancestor module call's `providers = { ...
Package providerscope resolves a resource's true root-level provider configuration address by walking every ancestor module call's `providers = { ...
Package providerversion answers issue #63: a configuration's provider pin and the admission table's evidence basis are two independent facts that can drift apart with nobody told.
Package providerversion answers issue #63: a configuration's provider pin and the admission table's evidence basis are two independent facts that can drift apart with nobody told.
Package refusalscan is the lockstep check behind GitHub issue #110's first acceptance criterion: a refusal cannot exist in a live package without an entry in that package's registry.
Package refusalscan is the lockstep check behind GitHub issue #110's first acceptance criterion: a refusal cannot exist in a live package without an entry in that package's registry.
Package registry loads the two committed join artifacts - live/mapping.json (issue #43, the TF-to-CFN type join) and live/registry.json (issue #42, the CloudFormation Registry's per-type roster) - and answers the one question discovery's Cloud Control fallback (#47) needs of them: given a TF resource type with no native provider list resource, is there a mapped CFN type that Cloud Control can enumerate on its own, with no per-call parsing of either file?
Package registry loads the two committed join artifacts - live/mapping.json (issue #43, the TF-to-CFN type join) and live/registry.json (issue #42, the CloudFormation Registry's per-type roster) - and answers the one question discovery's Cloud Control fallback (#47) needs of them: given a TF resource type with no native provider list resource, is there a mapped CFN type that Cloud Control can enumerate on its own, with no per-call parsing of either file?
Package slots is the set matcher for count instances: the rule that turns "N declared instances and M live resources" into a binding, without any index participating in identity.
Package slots is the set matcher for count instances: the rule that turns "N declared instances and M live resources" into a binding, without any index participating in identity.
Package stamp makes ownership markers something the tool guarantees rather than something the configuration author remembered to write.
Package stamp makes ownership markers something the tool guarantees rather than something the configuration author remembered to write.
Package staterecord is a small, versioned key/value Store with first-class conditional writes: Get, PutIfVersion, PutIfAbsent, Delete, List — nothing else.
Package staterecord is a small, versioned key/value Store with first-class conditional writes: Get, PutIfVersion, PutIfAbsent, Delete, List — nothing else.
Package strict holds the vocabulary of the live block's "strict" block: HANDOFF.md's principles, each expressed as a toggle with a default that is today's behavior.
Package strict holds the vocabulary of the live block's "strict" block: HANDOFF.md's principles, each expressed as a toggle with a default that is today's behavior.
Package uniquename reads one claim out of a piece of API documentation: that the name the CLIENT supplies for a resource is unique within the account and region the run is pointed at.
Package uniquename reads one claim out of a piece of API documentation: that the name the CLIENT supplies for a resource is unique within the account and region the run is pointed at.
Package untag is GitHub issue #67's apply-time half of the undeclared_tagged = "untag" verb: releasing one tag key from a live resource this estate owns but no configuration declares.
Package untag is GitHub issue #67's apply-time half of the undeclared_tagged = "untag" verb: releasing one tag key from a live resource this estate owns but no configuration declares.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL