Webエンジニアの森脇です。
LCLでは、普段使わないテストサーバなど常時稼働が不要なEC2インスタンスは、必要に応じて手動で起動・停止する運用にしています。が、停止を忘れて起動したままになっているということが、時々発生してしまっています。
大した金額ではないですが無駄は無駄なので、AWS CLIの勉強会を兼ねて、停止忘れを防止する仕組みを作りました。
仕組みの概要
AWS CLIを利用して、常時稼働が不要なインスタンスのステータスを定期的に取得し、"起動中"であればチャットへ通知します。
手順
インスタンスへのタグの付与
常時稼働が不要なインスタンスを識別するために、対象インスタンスには「env = spot」というタグを付与しました。
稼働中のインスタンスを取得
AWS CLIで対象インスタンスで稼働中のインスタンスのみを抽出します。
aws ec2 describe-instances --region ap-northeast-1 | jq '.Reservations[].Instances[] | select(.State.Name=="stopped" and .Tags[].Key=="env" and .Tags[].Value=="spot") | {"instance-id": .InstanceId, InstanceName: (.Tags[] | select(.Key=="Name").Value)} '
コマンドが長いので分けて解説します。
すべてのインスタンスの情報を取得します。
aws ec2 describe-instances --region ap-northeast-1
稼働中(state=running)のインスタンスかつ、env=spotのインスタンスを抽出します。 jsonの解析には、jqというコマンドを利用しています。
https://stedolan.github.io/jq/
jq '.Reservations[].Instances[] | select(.State.Name=="running" and .Tags[].Key=="env" and .Tags[].Value=="spot")
インスタンスidとインスタンス名を抽出します。(タグのNameにインスタンス名を設定しています)
{"instance-id": .InstanceId, InstanceName: (.Tags[] | select(.Key=="Name").Value)} '
チャットへの通知
Jenkinsで定期的に上述のコマンドを実行し、取得した結果を元にチャットワークAPIを呼び出し、チャットワークへ通知します。
自動で停止させることもできましたが、停止タイミングは人間が決めたいのでチャット通知に留めています。
まとめ
どのような仕組みにするかを考えるところから初めて、1時間ほどで作成しました。AWS CLIを初めて触ったメンバーもいましたが、AWS CLIにはそれほど苦戦せず、jqで目的の情報を取得することにかなり時間を費やしました。AWS CLI + jqを使えば、手軽に色々なことができそうです。