古い AMI をフィルタリングして削除する AMI Remover というツールを作った

Posted on

AWS で長年サービスを運用していると、不要なリソースが残ったままになって無駄なコストを払っていたということがよくあります。物理的なハードウェアがない分、不要なリソースを掃除する動機が起きにくいです。

freee では CodeBuild を使って AMI 作成を自動化していますが、削除するところまで自動化していなかったので古い AMI が増え続けていました。 AMI の削除(登録解除)は意外と面倒で、AMI とは別にそれに紐づく EBS スナップショットも削除する必要があります(課金されるのは EBS スナップショットの方)。

気づいたときに手動で少しずつ掃除はしていたものの、さすがに面倒になってきたので AMI Remover という CLI ツールを作りました。

以前作った aws-billing コマンドのように Golang で書いてみようと思いましたが、v3 の SDK を使ってみたかったので Ruby で書きました。

AMI Remover の機能

似たようなツールはいくつもあったのですが、自分が欲しい機能が揃っていませんでした。

具体的には、次の 3 つです。

  • Launch Configurations に紐づく AMI は削除しない
    • Launch Configurations に紐づく AMI を削除すると Auto Scaling で起動できなくなる
  • 指定した日数より古い AMI だけ削除したい
  • AMI のタグ名でフィルタリングしたい

詳しい使い方は README.md に書いてありますが、Launch Configurations に紐づく AMI は除外、また日数とタグ名はオプションで渡せるようにしています。

$ bundle exec ruby ami-remover.rb -h
Usage: ami-remover [options]
    -d, --days NUM
        --include-tag TAG
        --exclude-tag TAG
    -r, --remove
    -v, --verbose

オプションは組み合わせることができるので、作成してから 365 日が過ぎていて、かつ Project タグが付いている AMI だけを削除するということができます。

$ bundle exec ruby ami-remover.rb -r -d 365 --include-tag Project

バックアップ用途で作成した AMI はタグを付けて管理していると思いますが、そういう場合は --exclude-tag オプションで除外することもできます。

$ bundle exec ruby ami-remover.rb -r -d 365 --exclude-tag Backup

まとめ

大規模なサービスになると EBS スナップショットだけでもそれなりのコストになるので、こういう運用ツールを作って賢くコスト削減する必要があります。

freee の SRE メンバーは 3 人しかいないので、より本質的なことにフォーカスできるようにこれからもコードを書いて仕組みづくりを進めていきます。