
cloud-nuke(取扱注意)の時間フィルタでAWSリソースを削除してみた
はじめに
検証用のAWSアカウントを掃除したいとき、消したいのは「最近作ったもの」だけです。先週セットアップしたIAM roleやGitHub OIDCは残したいけれど、ここ2週間の検証スタックやbucketは全部消したい。
cloud-nukeには作成日時でリソースを絞る時間フィルタがあるので、それで試してみました。結論、やりたいことはできました。ただし作成日時を持たないリソースの扱いに癖があるので、そこを中心にまとめます。
検証環境
- macOS
- cloud-nuke v0.52.0(Homebrewでインストール。2026年7月時点の最新リリース)
- 検証専用のAWSアカウント(本番ではない。壊れてもCI/CDで作り直せる状態)
- 対象は
ap-northeast-1とglobal
cloud-nukeの時間フィルタ
時間指定はCLIフラグ2つだけです。
| フラグ | 意味 |
|---|---|
--older-than |
指定期間より古いものを削除 |
--newer-than |
指定期間より新しいものを削除 |
値はGoのduration形式なので、日付ではなく期間で書きます。2週間なら 336h(24 x 14)です。14d のような書き方はできません。
今回は「最近作ったものを消したい」ので --newer-than 336h を使います。
注意: cloud-nukeにはaws-nukeのような「設定ファイルにaccount aliasを書かないと実行できない」ガードがありません。フラグを渡した瞬間にそのアカウントが対象になります。アカウントの取り違えは自分で防ぐ必要があります。
最初に理解すべき罠: 作成日時を持たないリソース
ここが一番大事なところです。
AWSのAPIは、すべてのリソースに作成日時を返してくれるわけではありません。VPC、subnet、security group、internet gateway、route table、ENI、EIP、SNS topicなど、20種類以上のリソースタイプには作成日時がありません。
ではcloud-nukeはどうしているか。スキャンしたときに cloud-nuke-first-seen というタグを対象リソースに書き込みます。 次回以降はそのタグの値を作成日時の代わりに使う仕組みです。
これには2つの影響があります。
(1) inspect-aws は read-only ではありません。確認だけのつもりで実行しても、タグが書き込まれます。
(2) 初回スキャンでは first-seen が「今」になります。つまりすべてのリソースが「たった今作られた」ように見えます。
(2) が --newer-than と組み合わさると危険です。1年前に作ったVPCでも、初回スキャンなら「0秒前に作られたリソース」として --newer-than 336h に一致してしまいます。
逆に --older-than なら安全側に転びます。「0秒前のリソース」は古くないので、削除対象から外れるだけです。同じ仕組みが、フラグの向きによって安全にも危険にもなります。
対策は --exclude-first-seen フラグです。first-seenタグで年齢を判断するリソースを、まとめて対象外にします。今回は必ずこれを付けて実行しました。
手順
1. インストール
brew install cloud-nuke
2. AWSの認証情報を用意する
cloud-nukeは環境変数の認証情報を読みます。SSOでもlocal credentialsでも構いませんが、aws コマンドにaliasやプラグインを挟んでいる場合、cloud-nukeはそれを経由しません。
事前にAWSアカウント情報を確認してください。
aws sts get-caller-identity
3. inspect-aws で削除対象を確認する
まず消さずに一覧を出します。
cloud-nuke は v0.29.0 以降、実行したコマンド名・バージョン・AWSアカウントIDをGruntworkに送信します(IPアドレスやリソース名は送られません)。アカウントIDを外に出したくない場合は DISABLE_TELEMETRY で止められます。
export DISABLE_TELEMETRY=true
cloud-nuke inspect-aws --region ap-northeast-1 --region global \
--newer-than 336h --exclude-first-seen
--region global を忘れないようにします。IAMやS3はglobalリソースとして登録されているので、リージョンだけ指定していると出てきません。


4. --dry-run で本番のコマンドを空振りさせる
inspect-aws は別のコマンドなので、本番で使う cloud-nuke aws とは経路が違います。同じコマンドのまま安全に確かめたいときは --dry-run を付けます。
cloud-nuke aws --region ap-northeast-1 --region global \
--newer-than 336h --exclude-first-seen --dry-run
削除対象の一覧を出したところで止まります。確認プロンプトも出ません。
INFO Not taking any action as dry-run set to true.
つまり本番との差分は --dry-run の有無だけです。フラグの綴りミスやリージョンの指定漏れをそのまま確認できるので、inspect-aws よりこちらのほうが安心でした。
なお --dry-run でも一覧を作る処理は動くので、inspect-aws と同じように cloud-nuke-first-seen タグは書き込まれます。read-onlyではありません。


5. 実際に削除する
--dry-run を外すだけです。実行すると確認プロンプトが出ます。
cloud-nuke aws --region ap-northeast-1 --region global \
--newer-than 336h --exclude-first-seen



自分の環境では12件が対象になりました。2週間より前に作ったIAM roleやCloudFormationスタックはきちんと残っていて、作成日時での切り分けは期待通りに動きましたが、一部リソースの削除にエラーも出ました。
ERROR [Failed] iam-service-linked-role AWSServiceRoleForEC2Spot: polling IAM ServiceLinked
Role AWSServiceRoleForEC2Spot deletion: deletion task for IAM ServiceLinked Role
AWSServiceRoleForEC2Spot no longer exists but the role is still present
ERROR [Failed] iam-instance-profile <profile-name>: failed to get instance profile
<profile-name>: operation error IAM: GetInstanceProfile, https response error
StatusCode: 404, NoSuchEntity: Instance Profile <profile-name> cannot be found.
どちらもIAMなので、コンソールの IAM → ロール で名前を検索して確認したところ、2件とも実際には削除されていました。 CloudFormationスタックの削除で先に消えていたのだと思います。
削除全体のCloudTrail履歴でも確認してみました。

検出されなかったリソースもあった(2026年7月時点)
もうひとつ気になったのが、CloudFormationスタック配下にあるはずのリソースが inspect-aws の一覧に出てこないことでした。AWS CLIで数えると存在するのに、cloud-nukeは0件と言ってきます。
| リソースタイプ | 症状 |
|---|---|
cloudwatch-loggroup |
常に0件 |
lambda-layer |
常に0件 |
event-bridge-schedule |
常に0件 |
s3 |
us-east-1 以外のbucketが大半出てこない |
--log-level debug を付けると、いずれもタグ取得のAPI呼び出しが失敗していました。
cloud-nuke inspect-aws --region ap-northeast-1 --log-level debug \
--resource-type cloudwatch-loggroup \
--resource-type lambda-layer \
--resource-type event-bridge-schedule
DEBUG [cloudwatch-loggroup] Failed to list tags for log group /aws/lambda/...:
ValidationException: Invalid resourceArn
DEBUG [Failed] Unable to fetch tags for Lambda layer ...:
InvalidParameterValueException: Unsupported resource type for tagging or invalid arn
DEBUG [Event Bridge Schedule] Failed to list tags for schedule ...:
ValidationException: ... Member must satisfy regular expression pattern:
arn:aws[a-z-]*:scheduler:[a-z0-9\-]+:\d{12}:schedule-group\/[0-9a-zA-Z-_.]+
INFO Found total of 0 resources
リソース一覧を作る処理がタグを取りにいっていて、そこで失敗するとリソースがskipされているように見えます。しかもこのログは Debugf なので、デフォルトのログレベルでは何も出ません。「0件でした」としか言われないので気付きにくいのが厄介でした。
S3については実害に近いものもありました。3日前に作った中身入りのbucketが、--newer-than 336h の範囲内なのに出てきませんでした。今回は消したくないbucketだったので結果的に助かりましたが、逆のケースなら「消したはずが残る」ことになります。
なお検出されなかったlog group、Lambda layer、EventBridge scheduleは、削除後に確認したらすべて消えていました。CloudFormationスタックの削除に連鎖して消えたのだと思います。結果的に取り残しはゼロでした。
これは2026年7月時点のv0.52.0で確認した挙動です。リポジトリのmasterには関連しそうな修正が入っているので、新しいバージョンでは改善されている可能性があります。Homebrewで入るのは最新リリースであって最新masterではないので、気になる場合はバージョンを確認してみてください。
おわりに
「作成日時で絞って消す」は検証アカウントの掃除にかなり有効でした。残したいアカウント基盤に触らず、直近の検証ゴミだけを落とせます。コマンド自体は --newer-than 336h --exclude-first-seen を付けるだけなので、拍子抜けするほど簡単です。
気をつけるのは、作成日時を持たないリソースの扱いを理解してから使うこと。--newer-than は --older-than と違って、時刻が曖昧なリソースに対して危険な方向に倒れます。--exclude-first-seen を付けておけば、まずは事故りません。
もうひとつは、inspect-aws の結果を鵜呑みにしないことです。「0件」がバージョン由来の可能性はあります。消えたつもりのリソースが残っていないか、AWS CLIで一度突き合わせておくと安心です。同じ理由で、エラーが出ても本当に失敗したとは限りません。自分の目で確認するのがいちばん早いです。








