Appearance
Interruptions & Rescue
Use keel rescue when an interrupted infrastructure operation leaves a state lock or resources outside OpenTofu state.
Interrupting keel up and keel destroy
keel up and keel destroy run OpenTofu in a separate process group. Keel warns after each interrupt and requires four interrupts before aborting, which reduces the chance of leaving a partially applied stack. It handles SIGTERM from a closed terminal or canceled CI job the same way.
If an operation is aborted, the error points you at the repair:
the apply was stopped on request and may have left resources untracked;
run 'keel rescue' to checkkeel rescue
keel rescue requires admin access and reports problems by default. It checks:
- State locks: The report shows who acquired the lock, the operation, and its age.
- Untracked resources: AWS resources tagged for the app and environment but absent from OpenTofu state. These resources may continue to run and incur charges without being managed by later Keel commands.
Repairs are opt-in:
bash
keel rescue # report only
keel rescue --unlock # release the state lock (confirms; only when nothing holds it)
keel rescue --converge # re-run the apply — the repair for an interrupted keel up
keel rescue --finish-destroy # re-run the teardown, for an interrupted keel destroy--finish-destroy also accepts --delete-retained. Keel does not delete untracked resources automatically; it prints a deletion command for each one.
The Resource Groups Tagging API does not cover every resource type, so the untracked list may be incomplete. Keel also cannot read state while it is locked and reports tracked state as unknown in that case.
Releasing a state lock directly
When you already have the lock ID from an "Error acquiring the state lock" message:
bash
keel infra unlock <LOCK_ID> # admin; confirms first
keel infra unlock <LOCK_ID> --yes # for scriptsUse keel rescue --unlock to find and release a stale lock, or keel infra unlock when you already know the lock ID. Release a lock only after confirming that no operation is using it; concurrent writers can corrupt state.
What survives a destroy
Three account-wide DynamoDB tables sit outside individual app stacks: the app registry (keel-apps), deployment history (keel-deployments), and deploy locks (keel-deploy-locks). keel destroy releases the environment's deploy lock and removes it from the registry, but keeps deployment history by default. The dashboard marks history for environments that no longer exist. Remove it explicitly when needed:
bash
keel history prune # admin; confirms with the record count
keel destroy --prune-history # or in the same run as the teardown