Skip to content

Teardown

Deletes the whole CloudFormation foundation (VPC, subnets, security group, IAM role, S3 bucket, DynamoDB tables, event history) — a one-way door for the fleet’s shared infrastructure, not for any individual agent’s data (agents must already be gone before this runs).

Teardown’s first phase, agents_check, throws AGENTS_EXIST if any agent row is left (a legacy destroyed row does not count). Run hermetic agent destroy <name> --yes for each agent — it deletes the agent’s EBS volume unless you pass --keep-volume, and a kept one is what --delete-volumes below sweeps — before touching teardown at all; there is no flag that skips this check.

hermetic plan teardown [--no-purge] [--delete-snapshots] [--delete-volumes] [--no-reset-local]

Prints the same phases teardown will run and, separately, the checklist of things it will not do — see below. This is read-only: it takes none of the confirmation flags and mutates nothing.

hermetic teardown --yes [--confirm-account-id <12 digits>] \
[--no-purge] [--delete-snapshots] [--delete-volumes] [--no-reset-local]
Flag Default Consequence
--yes required gates the destructive command at all (assertConfirmable); does not by itself stand in for the account-id confirmation below
--no-purge purge on skip deleting the SSM parameters under /hermetic/ and /hermes/
--delete-snapshots off also delete DLM snapshots tagged hermetic:role=data
--delete-volumes off also delete leftover EBS volumes tagged hermetic:managed=true — destroys any agent memory/skills left on them, i.e. the volumes of agents destroyed with --keep-volume (and of any destroyed before delete became the default)
--no-reset-local reset on keep this home’s frozen config row instead of clearing it back to uninitialized; the local run log is archived either way
--confirm-account-id <digits> none supplies the typed-confirmation value non-interactively; without it, an interactive terminal prompts for the twelve digits, and a non-interactive one fails CONFIRMATION_REQUIRED

Teardown confirms the same way init --reset does: the frozen account’s twelve-digit id, typed back, never a bare y. hermetic teardown --yes alone in a script still fails — pass --confirm-account-id. hermetic apply <teardown-plan.json> goes through the identical ceremony: applying a kind: "teardown" plan requires --confirm-account-id too, and core independently re-checks the digits against the frozen config before doing anything.

hermetic teardown --yes # interactive: type the account id
hermetic teardown --yes --confirm-account-id 123456789012
hermetic teardown --yes --no-reset-local # keep this home frozen after teardown

agents_check → bucket (empty the versioned S3 bucket, required before CloudFormation will delete it) → stack (DeleteStack, waits for DELETE_COMPLETE) → tailscale (take hermetic's // hermetic:managed blocks back out of the tailnet policy) → ssm (if purge) → snapshots (if --delete-snapshots) → volumes (if --delete-volumes) → local (if reset_local) → done. tailscale comes before ssm because --purge deletes the OAuth secret that write authenticates with, and it can never fail the teardown: a policy hermetic cannot read or write goes back on the manual list below. The stack phase emits progress events on a timer while it waits, so a long delete (CloudFormation can legitimately take many minutes) doesn’t look hung.

Printed as warnings on every plan and on the final done event, and always present regardless of flags — hermetic has no API for any of these:

  • The Tailscale OAuth client itself — delete it by hand in the Tailscale admin console.
  • Any devices still listed on the tailnet.
  • The tagOwners line you pasted, and — only when the OAuth client could not write the policy file — hermetic’s own ssh and acls entries. With the policy_file scope the tailscale phase removes those two itself and the receipt says so; without it they are listed here with the reason.

Recovering from a partial teardown / DELETE_FAILED

Section titled “Recovering from a partial teardown / DELETE_FAILED”

If DeleteStack reports DELETE_FAILED, teardown throws an INTERNAL error carrying the AWS status reason — resolve whatever CloudFormation is stuck on (a resource it can’t delete, usually) and re-run hermetic teardown with the same flags. A retry after the stack (and its DynamoDB tables) is already gone is also safe: agents_check tolerates the agents table not existing at all and treats that as “nothing left to check,” so a teardown that got as far as deleting the stack but was interrupted before local can simply be re-run to finish the remaining phases.

The app refuses init (and every other mutating request, including a second teardown) with CONFLICT — teardown in progress for as long as a teardown op is running, including the moment after DELETE_COMPLETE while it is still swapping itself back to uninitialized. There is no way to race a fresh init against an in-progress DELETE_IN_PROGRESS stack — wait for the op to finish (or fail) and retry.