本日も乙

ただの自己満足な備忘録。

AWSインテグレーションによって削除されずに残ってしまったホストを自動削除する「Mackerenai」をつくった


(追記)

a-knowさんからコメントありまして、AWS側で削除されたリソースは、Mackerelでメトリック取得がされないため、ホスト料金に課金されないとのことでした。

改めてホスト数の計算に関するドキュメントを確認しました。

  • 1時間程度以内の間隔で定期的に、アクティブなホスト数をカウントします。
    • ホストのステータスに関わらず、メトリック投稿APIにアクセスしたユニークなホスト数を計上します。
      • ホストのステータスを poweroff などにしていても、メトリック投稿があるホストはアクティブなホストとしてカウントされます。
    • 通常はmackerel-agentの起動数となります。
    • 退役(Retired)状態のホスト・メトリックの投稿がおこなわれていないホストは、アクティブなホストとしてカウントされません。

https://mackerel.io/ja/docs/entry/faq/contracts/calculate-host-number


(挨拶)12月に入ってからバタバタしてブログ更新もままならずフラストレーションが溜まっているので来週から更新頻度を復活させます。

本記事は Mackerel Advent Calendar 2018 の12日目の記事です。

MackerelでAWSと連携する、AWSインテグレーション という機能があり、EC2以外にもRDSやRedshift、ElastiCacheなど様々なAWSリソースをホストとして登録して監視ができます。

とても便利な機能なのですが、(個人的に)改善してほしい点が2つあります。

  1. AWS上で削除したリソースがMackerel上に残ってしまう
  2. AWSリソース作成時に除外タグをつけてもタイミングによってはMackerelに登録されてしまう

1ですが、使わなくなったリソースをAWS上で削除してもMackerelで残ってしまうため、ホストの料金がかかってしまいます。
最近はEC2インスタンスの自動退役がリリースされましたが、他のリソースである、RDSやRedshift、ElastiCacheなどは依然として残り続けてしまいます。

mackerel.io

2については、例えば、RDSのリストアやClone *1 によってDBインスタンスを作成し、作成後に除外タグ *2 をつけるのですが、作成に時間がかかっていると、Mackerel側で登録されてしまいます。

1と2、ともにMackerelにホスト料金がかかってしまうので、不要なホストを退役しなければなりません。
手動による退役は骨が折れますし、非常に面倒なのでこれを自動化することにしました。

その自動化するツールが Mackerenai です。

github.com

名前の由来は Mackerel = マカレル = 監視する なので、逆に マカレナイ = 監視しない => Mackerenai であるという安直なところから来ています。

目次

どうやって不要なホストであると判断するのか

Mackerenai は不要であると判断したホストを退役します。
「ある期間(デフォルトは24時間)において特定のメトリクスが一つも収集されなければ、そのホストは使っていないので退役してもよい」 という判断基準で不要であると判断します。

対応しているAWSリソース及び判断に使っているメトリクスは以下の通りです。

  • EC2: custom.ec2.cpu.used (CPU使用率)
  • RDS: custom.rds.cpu.used (CPU使用率)
  • Redshift: custom.redshift.cpu.used (CPU使用率)
  • ElastiCache: custom.elasticache.cpu.used (CPU使用率)

使い方

このツールはAWS Lambdaによって動作します。 CloudWatch Events で実行するスケジュールを決めます。デプロイは AWS SAM によって行います。

# aws-sam-cli をインストールしておく
$ pip install aws-sam-cli
$ sam --version
SAM CLI, version 0.8.1

# git cloneしてくる
$ git clone git@github.com:ohsawa0515/mackerenai.git && cd mackerenai

# デプロイ
$ ./bin/deploy

デプロイするにあたっていくつかの設定値を環境変数で指定する必要があります。

  • MACKEREL_API_KEY : MackerelのAPIキー
  • RETIRE_DECISION_PERIOD_HOUR: ホストが不要であると判断する期間。デフォルトは24時間
    • 期間を短くすれば削除しやすくなりますが、 誤検知 する可能性が高くなります
  • RETIRE_DRY_RUN: ドライラン
    • true だと 削除(退役)しません。挙動を確かめるためにつかいます。デフォルトは true なので退役させるには明示的に false と指定する必要があります *3
  • SCHEDULE: スケジュール
    • CloudWatch Eventsのcron式を指定します。ドキュメント をご参照ください
  • REGION: AWS Lambdaを実行するリージョン。デフォルトは $ aws configure get region の実行結果

これらのパラメータを含めてデプロイすると以下のようになります。

# 東京リージョンにデプロイ。ホスト不要判断期間は12時間。ドライラン無効。日次 16:30 UTC+9 に実行
$ MACKEREL_API_KEY="xxxxx" \
  RETIRE_DECISION_PERIOD_HOUR=12 \
  RETIRE_DRY_RUN=false \
  SCHEDULE="cron(30 7 * * ? *)" \
  REGION=ap-northeast-1 \
  ./bin/deploy.sh

実行例

上記例で実行すると、CloudWatch Logsに以下のようにログが出力されます。
うちでは数百台のホストをMackerelで監視しているのですが、最小スペック(128MB) で約22秒程度かかりました。

mackerenai

まとめ

不要になったMackerel上のホストを自動的に削除するツールを紹介しました。
構想自体は先月ぐらいからあって、余裕をもってこのアドベントカレンダーに間に合わせたかったのですが、なんだかんだでギリギリになってしまいました。

ぜひ使ってもらってよければGitHubスターをお願いします!

*1:Auroraの機能

*2:タグによって登録するホストをフィルタできる機能

*3:デフォルトで false とすると意図せず使用中のホストも退役されてしまう可能性があるかもしれないのでまずはどんなホストが対象になるのかをドライランが有効になっている状態で確かめることをおすすめします