1年使った検証用個人AWSアカウント内のリソースを大掃除してみる
「AWSアカウントも大掃除だ」
時間で課金されるリソース(EC2、RDS)は都度削除しているのですが、課金されないリソース(IAMロールとか)を削除するのを忘れてしまうことがあります。
検証用のAWSアカウントを使い始めて1年ほど経ち、そこそこ検証時の残骸が溜まってきました。
AWSサービスやツールを活用して、不要リソースの削除をやってみます。
今回使用するAWSサービス・ツール
主に以下のAWSサービスとツールを使用します。
aws-nuke
AWSアカウント内のリソースを一括で削除することができるツールです。
フィルター機能などを使って、特定のリソースを削除から除外することもできます。
できるだけリソースを削除しますが、以下のようなリソースは残したいのでフィルター機能を使って除外していきます。
- ログイン用のIAMリソース
- terraformのstate保存用S3バケット
cdk bootstrap
時に作成されるCFnスタック
AWS Resource Explorer
AWS Resource Explorerはリソース検索および検出サービスです。
aws-nuke実行時に削除対象のリソースを表示できますが、フィルターの設定等によっては削除漏れがあるかもしれないため AWS Resource Explorer を併用します。
GUIで柔軟に検索条件も設定できますし、結果も見やすいです。
ちなみに、AWS Resource Explorerは無料で使用できます。
やってみる
不要なCloudFormationスタックの削除
最終的にはaws-nukeで一括削除します。
しかし、リソースが多いとaws-nukeの実行に時間がかかります。
少しでも実行時間を短くするために、削除可能なCloudFormationスタックは削除しておきます。
aws-nuke用のconfigファイルを作成
configファイルを用意します。
各自の環境によって、残したいリソースは変わってくると思うのでご参考までに。 (実際に使用した設定から、会社アカウント固有の情報を省略しています)
デフォルトVPCも削除する設定になっていますので、必要に応じて変更してください。
accounts
の部分は自分のAWSアカウントIDに置き換えてください。
regions: - ap-northeast-1 - global account-blocklist: - "000000000000" # dummy resource-types: excludes: # リソースが存在しないとERRORやWARNが出るサービスを除外(2022/12/23) # 実行結果のノイズになるため - FMSPolicy - FMSNotificationChannel - GlobalAccelerator - GlobalAcceleratorListener - GlobalAcceleratorEndpointGroup - WorkLinkFleet - MobileProject - SESReceiptRuleSet - SESReceiptFilter # 頻繁に作成するものではないので、除外 - ACMCertificate - CodeStarConnection - EC2KeyPair - Budget - Route53HostedZone - Route53ResourceRecordSet - CloudTrailTrail - ConfigServiceDeliveryChannel - ConfigServiceConfigurationRecorder # スキャン時間が長くなるため除外 - S3Object accounts: "123456789": presets: - "cdk" - "terraform" filters: IAMRole: - type: glob value: "my-role" IAMRolePolicy: - type: glob value: "my-role" IAMRolePolicyAttachment: - type: glob value: "my-role" - type: glob value: "AWSServiceRole*" S3Bucket: - type: glob property: Name value: "rain-artifacts-*" - type: glob property: Name value: "cf-templates-*" presets: cdk: filters: IAMRole: # cdk bootstrapで作成されるROLEのタグ名が、aws-cdk:bootstrap-role # ":"が含まれていて上手くglobで除外できていないから、role名で除外 - type: glob value: "cdk-*-role-*" IAMRolePolicy: - type: glob value: "cdk-*-role-*" IAMRolePolicyAttachment: - type: glob value: "cdk-*-role-*" S3Bucket: - type: exact property: tag:aws:cloudformation:stack-name value: "CDKToolkit" ECRRepository: - type: glob value: "*cdk-*-container-assets-*" SSMParameter: - type: glob property: tag:aws:cloudformation:stack-name value: "CDKToolkit" CloudFormationStack: - type: exact property: Name value: "CDKToolkit" terraform: filters: DynamoDBTableItem: - type: exact property: Table value: "terraform_state_lock" DynamoDBTable: - type: glob value: "terraform_state_lock" S3Bucket: - type: glob property: Name value: "terraform-state-*" CloudFormationStack: - type: exact propety: Name value: "terraform-backend" IAMUser: - type: exact value: "terraform-cloud-admin" IAMUserAccessKey: - type: exact property: UserName value: "terraform-cloud-admin" IAMUserPolicyAttachment: - type: exact property: UserName value: "terraform-cloud-admin"
regions
aws-nukeの対象にするリージョンを指定します。
検証時はほぼ東京リージョン(ap-northeast-1)を使うため、global(IAMとかRoute53)とap-northeast-1のみを指定しています。
どこのリージョンにリソースが残っているかを確認する際は、AWS Resource Explorerを確認すると分かりやすいと思います。
resource-types
excludes:
の部分で、除外するサービスを定義しています。
ACMやRoute53のホストゾーンなどは除外しています。
以下の基準で、除外するサービスを選びました。
- 検証時に使いまわすことが多い
- 課金が大きくない・または発生しない
またS3Object
に関しても除外しています。
理由としては、スキャン時間が伸びてしまうのとオブジェクトごとにDry-Runの結果に出力されるため、結果が見辛くなってしまうためです。
filterするにも大量のDry-Runの出力と向き合う必要があるため、aws-nukeでの一括削除の対象外としました。
オブジェクト削除したい場合は、マネジメントコンソールから「バケットを空にする」を実行する方が楽かもしれません。
accounts
filters
で除外するリソースを定義しています。
resource-types
のexcludes:
の部分と違って、サービス自体は削除に含めたいが一部リソースは対象外にしたいものを設定しています。
例) 検証用に適当に作ったS3バケットは削除したいが、terraformのstate管理用のバケットは残したいなど
accounts
のfilters
配下に全て記載しても動作は変わらないですが、presets
を使用するとスッキリかけるのでおすすめです。
aws-nuke Dry-Run(必要に応じてconfigの修正)
ローカル環境に直接aws-nukeをインストールして使用しても問題ありませんが、今回はDocker上で実行する方法を紹介します。
configファイルと同じディレクトリに、以下のdocker-compose.yml
を用意します。
version: "3" services: aws-nuke-dry-run: image: rebuy/aws-nuke:latest entrypoint: /usr/local/bin/aws-nuke --config /home/aws-nuke/config.yml --force --quiet volumes: - ./nuke-config.yml:/home/aws-nuke/config.yml - ~/.aws:/home/aws-nuke/.aws environment: - AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY - AWS_SESSION_TOKEN aws-nuke-run: image: rebuy/aws-nuke:latest entrypoint: /usr/local/bin/aws-nuke --config /home/aws-nuke/config.yml --force --quiet --no-dry-run volumes: - ./nuke-config.yml:/home/aws-nuke/config.yml - ~/.aws:/home/aws-nuke/.aws environment: - AWS_ACCESS_KEY_ID - AWS_SECRET_ACCESS_KEY - AWS_SESSION_TOKEN
ファイルを用意できたら、以下のコマンドでdry-runを実行します。(この時点ではリソースの削除は実行されません)
$ docker compose run aws-nuke-dry-run # 削除対象のリソース情報が表示される(省略) Scan complete: 648 total, 308 nukeable, 340 filtered.
上記の出力では、308個のリソースが削除の対象がとなっていました。
参考までに、私の環境で実行した際に数が多かった削除対象のリソースです。
- Cloudwatch Logs ロググループ: 60個
- IAMポリシー: 36個
他には、VPCやセキュリティグループもそれなりにありました。
aws-nuke RUN
Configの修正とDry-Run結果の確認が終わったら実際にリソースを削除します。
実際にリソース削除が発生するため、この手順はDry-Run結果を確認の上、自己責任で行なってください。
$ docker compose run aws-nuke-run Nuke complete: 0 failed, 189 skipped, 337 finished.
最終的には337個のリソースをaws-nukeで削除することができました。
AWS Resource Explorerでリソース削除を確認してみる
マネジメントコンソールから「AWS Resource Explorer」を選択して、状態を確認します。
私の場合は、PrefixListが削除から漏れていたことに気付いたので手動で削除しました。
おわりに
AWSアカウント内のリソースの大掃除でした。
1年ほど使っていたこともあり、検証の残骸が300程度と結構溜まっていました。
aws-nukeを使うことでスッキリ削除できました。 課金が大きいリソースはなかったため、コスト的には問題はありませんでしたが、不要なものを削除できたのでリソースの検索や参照が楽になりそうです。
AWS Resource Explorerはしっかり使ったことなかったのですが、今回の様なリソース棚卸しの際にはとても便利なサービスだと思いました。
aws-nukeの定期実行のやり方については、以下に書きましたので興味があったら読んでみてください。
以上、AWS事業本部の佐藤(@chari7311)でした。