{"id":13718929,"url":"https://github.com/nirdosh17/cfn-teardown","last_synced_at":"2026-03-04T23:31:30.380Z","repository":{"id":47622225,"uuid":"395857917","full_name":"nirdosh17/cfn-teardown","owner":"nirdosh17","description":"CLI to efficiently cleanup tightly dependent AWS CloudFormation stacks.","archived":false,"fork":false,"pushed_at":"2024-08-15T19:38:17.000Z","size":141,"stargazers_count":17,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-21T08:13:54.366Z","etag":null,"topics":["aws","cfn","cleanup-script","cli","cloudformation","cloudformation-stacks","delete","go","golang","teardown"],"latest_commit_sha":null,"homepage":"https://medium.com/p/32e69f9b62f9","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nirdosh17.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"nirdosh","thanks_dev":null,"custom":null}},"created_at":"2021-08-14T02:02:09.000Z","updated_at":"2024-10-30T21:35:24.000Z","dependencies_parsed_at":"2024-08-15T20:55:43.839Z","dependency_job_id":null,"html_url":"https://github.com/nirdosh17/cfn-teardown","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/nirdosh17/cfn-teardown","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirdosh17%2Fcfn-teardown","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirdosh17%2Fcfn-teardown/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirdosh17%2Fcfn-teardown/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirdosh17%2Fcfn-teardown/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nirdosh17","download_url":"https://codeload.github.com/nirdosh17/cfn-teardown/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nirdosh17%2Fcfn-teardown/sbom","scorecard":{"id":688801,"data":{"date":"2025-08-11","repo":{"name":"github.com/nirdosh17/cfn-teardown","commit":"7002d1a2881774979f6438b5e1d8c7c061179cd8"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/20 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yaml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/release.yaml:9"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.0.0 not signed: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/170420558","Warn: release artifact v0.1.2 not signed: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/48217199","Warn: release artifact v0.1.1 not signed: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/48190057","Warn: release artifact v0.1.0 not signed: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/47986892","Warn: release artifact v1.0.0 does not have provenance: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/170420558","Warn: release artifact v0.1.2 does not have provenance: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/48217199","Warn: release artifact v0.1.1 does not have provenance: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/48190057","Warn: release artifact v0.1.0 does not have provenance: https://api.github.com/repos/nirdosh17/cfn-teardown/releases/47986892"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/nirdosh17/cfn-teardown/release.yaml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yaml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/nirdosh17/cfn-teardown/release.yaml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yaml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/nirdosh17/cfn-teardown/release.yaml/main?enable=pin","Warn: containerImage not pinned by hash: test/Dockerfile:1: pin your Docker image by updating ubuntu to ubuntu@sha256:7c06e91f61fa88c08cc74f7e1b7c69ae24910d745357e0dfe1d2c0322aaf20f9","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Info: 'branch protection settings apply to administrators' is required to merge on branch 'main'","Warn: could not determine whether codeowners review is allowed","Warn: no status checks found to merge onto branch 'main'","Warn: PRs are not required to make changes on branch 'main'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 15 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2022-0635","Warn: Project is vulnerable to: GO-2022-0646","Warn: Project is vulnerable to: GO-2022-0493 / GHSA-p782-xgp4-8hr8","Warn: Project is vulnerable to: GO-2021-0113 / GHSA-ppp9-7jff-5vj2","Warn: Project is vulnerable to: GO-2022-1059 / GHSA-69ch-w2m2-3vjp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T01:45:26.852Z","repository_id":47622225,"created_at":"2025-08-22T01:45:26.852Z","updated_at":"2025-08-22T01:45:26.852Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30099347,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T23:31:22.529Z","status":"ssl_error","status_checked_at":"2026-03-04T23:31:22.112Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws","cfn","cleanup-script","cli","cloudformation","cloudformation-stacks","delete","go","golang","teardown"],"created_at":"2024-08-03T01:00:39.597Z","updated_at":"2026-03-04T23:31:30.357Z","avatar_url":"https://github.com/nirdosh17.png","language":"Go","funding_links":["https://buymeacoffee.com/nirdosh"],"categories":["CLI Tools"],"sub_categories":["Hooks"],"readme":"[![Go Report Card](https://goreportcard.com/badge/github.com/nirdosh17/cfn-teardown)](https://goreportcard.com/report/github.com/nirdosh17/cfn-teardown)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/nirdosh17/cfn-teardown/blob/main/LICENSE)\n![Latest GitHub Release](https://img.shields.io/github/release/nirdosh17/cfn-teardown)\n\n# CFN Teardown\nCleanup CloudFormation stacks respecting the order of dependencies.\n\n## Features\n\n- Stack name pattern matching for deletion. Finds out dependent/importer/child stacks recursively from a root stack.\n\n- Builds dependency tree for faster teardown. Dependency tree also gives insight on loose/tight coupling of the stacks.\n\n- Multiple safety checks to prevent accidental deletion.\n\n- Supports slack notification for deletion status updates via webhook.\n\n---\n\n### Install\nDownload binary for the appropriate platform from [HERE](https://github.com/nirdosh17/cfn-teardown/releases).\n\n```bash\n✗ wget -q https://github.com/nirdosh17/cfn-teardown/releases/download/v1.0.0/cfn-teardown_Linux_x86_64.tar.gz\n✗ tar -xzf cfn-teardown_Linux_x86_64.tar.gz\n✗ touch ~/.cfn-teardown.yaml \n\n✗ ./cfn-teardown version\nUsing config file:  /Users/nirdosh/.cfn-teardown.yaml\nVersion:  v1.0.0\n```\n\n---\n### Usage\nRequired global flags for all commands: `STACK_PATTERN`, `AWS_REGION`, `AWS_PROFILE`\n\n1. Run `cfn-teardown -h` and see available commands and needed parameters.\n\n2. Listing stack dependencies: `cfn-teardown listDependencies`\n\n\t_Generates dependencies in  `stack_teardown_details.json` file (printed in terminal as well)_\n\n2. Tear down stacks: `cfn-teardown deleteStacks`\n\n\t_Deletes matching stacks and updates status in the teardown details file as the script is running._\n\n---\n\n### Selecting Stacks For Deletion\n**For stacks with consistent naming convention:**\n\nLet's say you have stacks starting with the environment name followed by a hyphen:\n- _qa-shared-networks_\n- _qa-service-user-management_\n- _qa-service-user-search_\n\nIn this can, you need to set stack pattern as `^qa-` to match stacks starting with `qa-`.\n\n**For stacks which do not follow any naming pattern:**\n\nExample:\n- _qa-shared-networks_\n- _service-user-management_ (depends on shared networks stack)\n- _user-search-service_ (depends on shared networks stack)\n\nUse the root stack's name as the stack pattern i.e. `^qa-shared-networks`. The script will find out all dependendent stacks from the root stack **recursively** until the leaf nodes have zero importer stacks.\n\n---\n### Configuration\n\nConfiguration for this command can be set in three different ways in the precedence order defined below:\n1. Environment variables(same as flag name)\n2. Flags e.g. `cfn-teardown deleteStacks --STACK_PATTERN=qaenv-`\n3. Supplied YAML Config file (default: ~/.cfn-teardown.yaml)\n    \u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eMinimal config file\u003c/b\u003e\u003c/summary\u003e\n\n    ```yaml\n    AWS_REGION: us-east-1\n    AWS_PROFILE: staging\n    STACK_PATTERN: qa-\n    ```\n    \u003c/details\u003e\n    \u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eAll configs present\u003c/b\u003e\u003c/summary\u003e\n\n    ```yaml\n    AWS_REGION: us-east-1\n    AWS_PROFILE: staging\n    TARGET_ACCOUNT_ID: 121212121212\n    STACK_PATTERN: qa-\n    ABORT_WAIT_TIME_MINUTES: 20\n    STACK_WAIT_TIME_SECONDS: 30\n    MAX_DELETE_RETRY_COUNT: 5\n    SLACK_WEBHOOK_URL: https://hooks.slack.com/services/dummy/dummy/long_hash\n    ROLE_ARN: \"\u003carn\u003e\"\n    DRY_RUN: \"false\"\n    ```\n    \u003c/details\u003e\n\nSee available configurations via: `cfn-teardown \u003ccommand\u003e --help`\n\n---\n### Stack Teardown Strategy\n\n1. Find matching stacks based on the regex provided\n\n2. Prepare stack dependencies\n    \u003cdetails\u003e\n    \u003csummary\u003e\u003cb\u003eIt looks something like this:\u003c/b\u003e\u003c/summary\u003e\n\n      ```json\n      {\n        \"staging-bucket-archived-items\": {\n          \"StackName\": \"staging-bucket-archived-items\",\n          \"Status\": \"CREATE_COMPLETE\",\n          \"StackStatusReason\": \"\",\n          \"DeleteStartedAt\": \"2021-02-07T03:35:43Z\",\n          \"DeleteCompletedAt\": \"\",\n          \"DeletionTimeInMinutes\": \"\",\n          \"DeleteAttempt\": 0,\n          \"Exports\": [\n            \"staging:ItemsArchiveBucket\",\n            \"staging:ItemsArchiveBucketArn\"\n          ],\n          \"ActiveImporterStacks\": {\n            \"staging-products-service\": {}\n          },\n          \"CFNConsoleLink\": \"https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/stackinfo?stackId=staging-bucket-archived-items\"\n        },\n        \"staging-products-service\": {\n          \"StackName\": \"staging-products-service\",\n          \"Status\": \"CREATE_COMPLETE\",\n          \"StackStatusReason\": \"\",\n          \"DeleteStartedAt\": \"2021-02-07T03:30:54Z\",\n          \"DeleteCompletedAt\": \"\",\n          \"DeletionTimeInMinutes\": \"\",\n          \"DeleteAttempt\": 0,\n          \"Exports\": [\n            \"staging:ProductsServiceEndpoint\"\n          ],\n          \"ActiveImporterStacks\": {},\n          \"CFNConsoleLink\": \"https://console.aws.amazon.com/cloudformation/home?region=us-east-1#/stacks/stackinfo?stackId=staging-products-service\"\n        }\n      }\n      ```\n    \u003c/details\u003e\n\n3. Alert slack channel(if provided) and waits before initiating deletion. Starts deletion immediately if no wait time is provided.\n\n4. Select stacks which are eligible for deletion. A stack is eligible for deletion if it's exports are imported by no other stacks. In simple terms, it should have no dependencies.\n\n5. Send delete requests for all selected stacks.\n\n6. Wait for 30 seconds(configurable) before scanning eligible stacks again. Checks If the stack has been already deleted and if deleted updates stack status in the dependency tree.\n\n7. This process (sending delete requests, waiting, checking stack status) is repeated until all stacks have status `DELETE_COMPLETE`.\n\n8. If a stack is not deleted even after exhausting all retries(default 5), teardown is halted and manual intervention is requested.\n\n---\n\n### AWS Credentials\nOnly AWS profile based authentication supported at the moment. By default, it tries to use the IAM role of the caller but we can also supply role arn if we want the script to assume a different role.\n\n---\n\n### Safety Flags\n\n- `DRY_RUN` flag must be explicitely set to `false` to activate delete functionality\n\n- `ABORT_WAIT_TIME_MINUTES` flag lets us to decide how much to wait before initiating delete as you might want to confirm the stacks that are about to get deleted\n\n- `TARGET_ACCOUNT_ID`: If provided, this flag confirms that the given aws account id matches with account id in the aws session during runtime to make sure that we are deleting stacks in the desired aws account\n\n---\n\n### Limitation\nIf a stack can't be deleted from the AWS Console itself due to some dependencies or some error, then it won't be deleted by this tool as well. In such case, manual intervention is required.\n\n---\n\n### Demo\n\u003e \u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eDeleting Stacks\u003c/strong\u003e\u003c/summary\u003e\n\u003e \u003cimg src=\"https://user-images.githubusercontent.com/5920689/130366139-30912d09-7d79-4537-8809-014c75ce38c0.gif\" width=\"600\" alt=\"deleting stacks\" /\u003e\n\n\u003e \u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eSlack Notifications\u003c/strong\u003e\u003c/summary\u003e\n\u003e \u003cimg src=\"https://user-images.githubusercontent.com/5920689/130365254-dd2d911d-803b-4c02-93ec-2f78badedb6a.png\" width=\"600\" alt=\"slack notifications sample\" /\u003e\n\n\n---\n### Caution :warning:\n_With great power, comes great responsibility_\n- First try within small number of test stacks in dry run mode.\n- Use redundant safety flags `DRY_RUN`, `TARGET_ACCOUNT_ID` and `ABORT_WAIT_TIME_MINUTES`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirdosh17%2Fcfn-teardown","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnirdosh17%2Fcfn-teardown","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnirdosh17%2Fcfn-teardown/lists"}