Skip to content
cdkd

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.

Last updated: