LoginSignup
3
1

More than 5 years have passed since last update.

無駄金を取られないようにするために使ってないEC2を自動停止するスクリプトを書いてみた

Last updated at Posted at 2018-10-08

はじめに

検証用にマシンに思ったよりパワーが必要だったので、短時間だからいっか、という軽い気持ちで m5.xlarge にパワーアップさせた。
検証自体は無事に終わって、後日ログ採取を取るために起動したのだが、仕事の合間だったのでログ採取してあとに停止するのをすっかり忘れてしまい3日ほど起動しっぱなしに。。。。
さすが m5.xlarge たかが3日とは言え請求が結構エグい。
とても悲しい気持ちになったので使っていないEC2を自動で停止するスクリプトを描くことにした。

TL;DR

だれ向け?

  • 私と同じ悲しみにくれている方
  • 個人のAWSアカウントでごにょごにょされること方
  • 会社の検証環境のEC2料金が高くて悩んでいる方

スクリプト

5分毎にCPU、Inbound通信、SSH接続をチェック
10回連続でin-activeだった場合、つまり50分間in-activeな場合にサーバをシャットダウンする例

crontab
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/aws/bin:/root/bin:/opt/aws/bin
MAILTO=""

*/5 * * * * cd ~; /bin/bash /root/monitor.sh; [ `tail -n 10 /root/monitor.log | grep -P "^active" | wc -l` -eq 0 ] && halt -h now || echo no shut >> /root/log.txt

サーバが利用状態かそうでないかをチェックするスクリプト
5秒間の平均CPU利用率2%以上、10秒間のInbound通信が1024Byte以上、SSH接続が有る場合にActiveと判断する

monitor.sh
#!/bin/bash
cpu_usage=2
net_usage=1024
ssh_session=1
status=0
log='monitor.log'

# The first report of vmstat gives averages since the last reboot, drop it.
# Adopt average CPU usage rate for 5 seconds
cpu_usage_usr=$(vmstat 1 10 | tail -5 | awk '{sum+=$13} END {print sum/NR}')

# Adopt inbound traffic received in 10 seconds.
net_usage_usr=$(for i in `seq 1 2`; do cat /proc/net/dev; sleep 10; done | grep eth0 | awk 'NR==1{m=$10}NR==2{print $10-m}')

# Determine whether there is an SSH connection.
ssh_session_count=$(/usr/sbin/ss | grep '[s]sh' | wc -l)

if [ `echo "$cpu_usage_usr > $cpu_usage" | bc` == 1 -o `echo "$net_usage_usr > $net_usage" | bc` == 1 -o $ssh_session_count -ge $ssh_session ]; then
  status=1
fi

[ $status -eq 0 ] && status_str='in-active' || status_str='active'
echo $status_str $cpu_usage_usr $net_usage_usr $ssh_session_count >> $log

exit 0

解説

元ネタ様はこちらです。
一定時間利用されていないEC2インスタンスを自動でstopする

何番煎じかわからないですが、EC2のみで実装できてサクッと仕込める方法は見つからなかったのでこちらに記録しておきます。

ほぼ元ネタ記事そのままなのですが、自分用に修正した点は以下

要件

  • 個人もしくは極少数しか使わない環境なので間違って落ちちゃっても問題にはならない
  • コピペレベルで簡単に設定できること(設定の手間が増えると後回しにされて結局はじめにの悲劇が起こるため)
  • webアプリがメインのためInbound通信も監視対象にする
  • SSHで作業中は停止されたくない

方針

  • シェルスクリプト+Crontabのみで実装
  • 5秒間の平均CPU使用率が2%を超えている場合はActive
  • 10秒間のInbound通信が1024Byteを超えている場合はActive
  • SSH接続があればActive
  • In-Activeが50分連続して続いてたらサーバシャットダウン

課題

  • 運悪く起動時にCronが走ると停止されちゃう。起動後10分は監視対象外のような条件付けの検討が必要
  • 厳密にはSSHで作業しているときはActiveにしたいだけで、無操作の場合はIn-Activeにしたい。Oubgoing通信も監視するとか、auditlog残すようにしてログのタイムスタンプで判断するとかもう一捻りが必要

参考リンク

【AWS】CloudWatch入門/使っていないEC2を自動シャットダウンしよう
一定時間利用されていないEC2インスタンスを自動でstopする

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1