The state store
Because cdkd does not deploy through CloudFormation, there is no server-side
stack to ask about a deployment. What cdkd created is recorded in an S3
state store instead — one JSON record per (stack, region) pair, under
s3://<bucket>/cdkd/<stackName>/<region>/state.json. That record is the
source of truth for every later operation: what a diff compares against, what
a drift check baselines on, and what a destroy walks to know which physical
resources to delete.
The consequence worth knowing is that this store is addressable on its own.
CloudFormation ties every operation to a stack you name; the cdkd state store
holds the whole estate in one place, so cdkd state can enumerate it, act on
several stacks at once, or — with cdkd state destroy --all and
cdkd state refresh-observed --all — act on every stack in the bucket:
cdkd state info # which bucket cdkd is using, and how much is in it
cdkd state list # every stack in the bucket, not just this app's
cdkd state list --tree # nested-stack parents and children
cdkd state show MyStack # one record in full, including resource properties
cdkd state destroy --all --yes # tear the entire estate down in one command
No CDK app required
None of these commands synthesizes. They read the bucket, so they work from a
machine that never had the repository — which is what makes them the cleanup
path for a CI runner whose branch has been deleted, or for a stack whose source
is simply gone. cdkd state destroy runs the identical deletion pipeline as
cdkd destroy, sourced from the record rather than from a fresh synth.
The price of that independence is that stacks are identified by their physical
CloudFormation names — the CDK display paths and wildcards cdkd destroy
accepts are not available without an app to resolve them against.
Removing a record is not deleting resources
Two operations look similar and are not: cdkd state destroy deletes the AWS
resources and then the record, while cdkd state orphan deletes only the
record and leaves everything running. Orphaning is the escape hatch for a
resource cdkd can no longer manage — and it is a sharp one, because the
resources it leaves behind are no longer tracked by anything. See
Orphan vs Destroy for which of the four cleanup
commands applies.
Records outlive the binary that wrote them
The record carries a schema version, and every older version is read and upgraded in memory by the current binary; the next write persists the new shape silently. Upgrading cdkd never asks you to migrate a record's contents.
Two things around the record are not covered by that. A record still written
under the original key layout, from before keys carried a region, is rewritten
under the current one by the next cdkd deploy into that region. And the
bucket name changed once: installations predating the region-free default
need a one-time cdkd state migrate per region, which both the deprecation
warning and cdkd state info point at.
See cdkd state for the full reference: every subcommand,
its flags, the confirmation and lock behavior, and the exit codes. The record
schema itself — every field, the v1 → v9 history, and the lock mechanism — is
documented in State Management.