Skip to main content
Destructive command. This permanently deletes AWS resources. Back up data first.

Overview

fjall destroy <app> deletes the AWS resources for one application, in reverse dependency order. The positional argument is application-only. Tier teardown uses noun-verb commands instead: fjall org destroy, fjall platform destroy, fjall account destroy. Passing organisation, platform, account or domain as the positional fails before authentication with a teaching error naming the right spelling. Nothing is validated and nothing is destroyed:

Prerequisites

Without the infrastructure file, destroy stops with No infrastructure.ts found and does no AWS work.

Usage

Destroy an application

Fjall deletes the application’s CloudFormation stacks in this order, skipping stacks the application does not declare: Compute goes before the database, and the network stack goes last, so nothing is deleted while a dependent stack still references it. The us-east-1 log-delivery stack goes first because its delivery references the distribution and the log bucket across regions. The us-east-1 certificate stack goes after the CDN stack because the distribution references the certificate.

What survives the destroy

The application itself survives. fjall destroy removes infrastructure. The application stays registered with Fjall, keeps its name, and keeps counting against your plan’s application limit. That is deliberate: the registration is the thing your plan counts, and it is what lets you redeploy the same application later without recreating it. It also means destroying an application does not get an organisation back under its limit. If that is what you are trying to do, the verb is fjall apps deregister:
De-registration removes the record and nothing else, so run fjall destroy <app> first if you want the AWS resources gone. Afterwards the CLI can no longer address the application by name. Removal policies come from the target account’s environment, not from a flag on the command. Accounts stamped production default to RETAIN, so their data resources outlive the stack delete. Every other stage (staging, development, platform, compliance) defaults to DESTROY. Check which account a target maps to with fjall target list before you destroy anything in a staging or development account.

Tear down tier infrastructure

Tier teardown is noun-verb. Each command registers only the flags its tier honours.
A production or compliance account with a DR region set keeps its disaster-recovery backup vault through the teardown. The vault backupVault and its KMS key are declared RETAIN, so both stay in the account and the recovery points outlive the stack.The vault keeps its name. The key does not keep its alias: alias/cmk/backupVault/backupVault is deleted with the stack, so afterwards the key is addressable by key id or ARN. The retained key carries a fjall:kms:alias tag holding the alias it had, which is how you find it.The CLI’s own screens below still describe the account stack as removing “backup vaults”.
A later fjall account deploy into that account re-owns the survivor rather than creating a second vault under the fixed name (see Deploy Account). To free the name, copy the recovery points you need elsewhere and delete the vault by hand.

Cascade control

fjall org destroy cascades by default, tearing down every member account first, then the platform, then the organisation stack:
Pass --no-cascade to destroy the organisation stack alone:
--no-cascade exists on fjall org destroy only. fjall destroy, fjall platform destroy and fjall account destroy reject it as an unknown option, and neither the platform nor the account teardown ever cascades.

Interactive flow

Run fjall destroy with no argument for a guided teardown:
Application loads the applications registered for your organisation and asks which one:
Organisation lists only the tiers scaffolded in the current project:
With no tier scaffolded locally, the screen prints No organisation infrastructure found. / Nothing to destroy. and exits. Selecting Organisation then asks about the cascade, defaulting to No:
The pickers appear only when you run fjall destroy bare. Passing a target (fjall destroy api, fjall org destroy) jumps straight to the confirmation, so on fjall org destroy the cascade is controlled by --no-cascade rather than by the prompt.

Confirmation

The final gate is a typed confirmation, not a yes/no prompt. Type the target name exactly (case-insensitive) to proceed:
--force or --skip-confirmation replaces the typed gate with a skipped step:
In a non-interactive shell, one of those two flags is mandatory. Without either, destroy exits with a validation error:

Arguments

Options

--target selects which account and region the credentials come from. The positional argument stays the application name. Before it deletes anything, fjall destroy asks CloudFormation for each of the application’s stacks and refuses while any is mid-operation:
From fjall 38 each stack is checked in its own region, so a <App>UsEast1Certificates or <App>UsEast1CdnLogging stack mid-operation in us-east-1 blocks the destroy too. -f, --force skips this check as well as the typed confirmation.

Agent options

For AI-agent and scripted use, destroy also accepts the standard agent flags: Without --force or --skip-confirmation, agent mode returns a structured destructive-confirmation gate naming the exact command to re-run. The MCP server’s destroy tool takes consent itself: a bare call asks the host to confirm before anything is spawned, and passes --skip-confirmation to this CLI only once the user has answered yes. See Agent mode.

Tier destroy options

fjall org destroy, fjall platform destroy and fjall account destroy take -f, --force, --skip-confirmation and --target <target>, plus the standard and agent flags above. --no-cascade is available on fjall org destroy only. --target is refused on fjall org destroy, because organisation infrastructure always deploys to the management account:

Aliases

destroy has one alias, delete:
fjall remove is not a destroy alias. It is the codemod command that removes a single resource from an application’s infrastructure.ts source file. It deletes no deployed AWS resources. See fjall remove.

Examples

Common issues

Stack stuck in DELETE_FAILED

CloudFormation reports the resource blocking the delete. Open the stack’s Events tab in the CloudFormation console, clear the blocker, then run the same fjall destroy command again.

S3 bucket not empty

Fjall empties buckets tagged for auto-delete before deleting the stack. Buckets without that tag are left in place and can block the delete. Empty them, then re-run the destroy.

RDS deletion protection enabled

Deletion protection blocks the stack delete while it is on. Disable it in the RDS console, then re-run the destroy.

CloudFormation could not confirm a stack

When the application no longer synthesises a stack the deploy state still lists, Fjall asks CloudFormation whether it is really gone before skipping it. If that read fails, the destroy stops and deletes nothing:
Run the command the error names, clear the cause (usually an expired session or a throttled region), then re-run the destroy. The <App>UsEast1Certificates and <App>UsEast1CdnLogging stacks live in us-east-1 whatever the deploy target’s region is, so the region in the error is theirs, not the target’s. Next.js and Payload applications are the exception. They destroy their database, messaging and storage stacks together in one phase, and that phase still takes CDK’s word that a stack is gone. A database, messaging or storage stack the deploy state lists that the application no longer synthesises is reported as destroyed, not skipped, and any such stack still in CloudFormation is left in the account. Check those three stacks in the CloudFormation console after destroying a Next.js or Payload application. Those two us-east-1 stacks always destroy on their own, so they are always probed.

Retry, then fall back

  1. Read the CloudFormation events for the failed stack.
  2. Clear the blocker (empty the bucket, disable the protection).
  3. Re-run the same fjall destroy command. Destroy is re-runnable, and a stack the deploy state lists that the application no longer synthesises is probed in its own region before it is skipped. If it is still there it is deleted in that region, and if the probe fails the destroy stops and deletes nothing (see CloudFormation could not confirm a stack, which also names where the probe does not run).
  4. Delete the remaining stack from the AWS Console as a last resort.

Before you destroy

  1. Snapshot the database. RDS and Aurora take a final snapshot on delete, and production instances retain their automated snapshots. Confirm the snapshot exists in the RDS console before you start.
  2. Copy bucket contents you need. Anything in a bucket tagged for auto-delete goes with the stack.
  3. Export the logs you want to keep. CloudWatch log groups are deleted with their stack.
  4. Check what the application declares. Run fjall list -a api to see every resource in the application’s infrastructure.ts.
  5. Rehearse in a non-production account first.
After the destroy finishes, confirm in the AWS Console that the stacks are gone and that billing for those resources has stopped.
CloudFormation stacks can take 5-10 minutes to delete. A cascading fjall org destroy across several member accounts takes considerably longer.

Next Steps

fjall deploy

Redeploy an application or tier infrastructure.

fjall remove

Remove one resource from infrastructure.ts without touching AWS.

fjall list

Inspect the resources an application declares.

fjall restore

Restore data from a snapshot after teardown.