Denen blog

株式会社電縁の社員によるブログです。

AWS(EC2)の自動停止をやってみる

f:id:yasuaki-sakai:20170607123057j:plain

こんにちは、飲み会大好き内山です。

そろそろ夏ですね。そろそろプレミアムマンデーでもしてビアガーデンに行きたいですねー。

今回は真面目に技術関連のネタを書きます。

AWS(EC2)

AWS(EC2)良いですよね。ちょくちょく使ってます。
ちょっと試したいツール入れみたり、自分用の自由にできる環境作ってみたり
簡単なアプリケーションサーバ立てたり、etc。

案件・プロジェクトとは別に、チーム内のツールとか情報共有とか
暇になったときにちょっとサーバ立てるのになんだかんだ使ってます。

とりあえずやって不要なら壊す。既存の環境や社内サーバのリソースを意識しないで
気軽にいじることができるのは精神的にとても健康的な手段だと思ってます!

ただ、AWSをやっていて気にするのが「料金」。
1時間あたりが安くてもやはり常時起動しっぱなしだと塵が積もってそこそこの金額になりますよね。
遊びで利用しているとな放置していると意味もなく使用量が積重なってしまい罪悪感が結構あります。

不要なときに止めればよし、と思うのですがどうしても忘れてしまうんですよね。よくやらかしてました。
料金がかかってしまうと気軽に使えなくなってしまったり、上からの目につけられてしまいます。

みんなが安心して使える工夫をしたいですよね。

上記の問題を解決するために、
現在、特定の時間になったら自動的にインスタンスを停止するように1台のEC2サーバからシェルを実行してます。
今回のはそのノウハウを共有したいと思います。

■EC2の自動停止

やりたいことは下記

  1. EC2のインスタンスを一定時刻で自動で停止させたい。
  2. 停止したことを通知したい。(Webhook)
  3. 常駐起動用のインスタンスは停止させたくない。(ホワイトリスト化)
  4. なるべく低コストにしたい。

実現方法は下記

  • AWS CLIインスタンスの状態を取得、停止する。
  • 常駐起動のEC2にCRONを設定して、一定時間で停止させる
  • Webhookはcurlで送信

 

やっていることはだいぶ単純です。
AWS CLIインスタンスの一覧取得コマンドを実行、その後、起動中のものに関して、停止コマンドを実行
その際に、インスタンスIDでホワイトリストを用いて判定する。
そして結果を対象のWebhook先の形式に併せてCurlするだけです。
ポイントは

  • AWS CLIを流れるように設定を行うこと。
  • AWS CLIの戻り値をJSON形式に設定すること。
  • jqを利用するとバースなどのJSONの処理がコマンドで簡単に扱える。

以下にサンプルコードを記載します。

#!/bin/sh
#停止させないIDをパイプ区切りにする
WHITE_IDS="i-test|addmore"
TCR_URL=WEBHOOKURL

################################## 
##[起動中のインスタンスIDの取得]
################################## 
#InstanceStatusesの配列の中からInstanceIdとInstanceState.Nameを取り出す。
STS_MAP=`aws ec2 describe-instance-status | jq -r '.InstanceStatuses[] |  { (.InstanceState.Name ): .InstanceId}'`

#起動中のインスタンスIDのみ取り出す
IDS=`echo ${STS_MAP} | jq -r '.running'`

################################## 
##[メイン処理]
################################## 
## 指定EC2インスタンスの停止(stop).
if [ -n "$1" ] && [ $1 = '--stop' ] ; then
    for ID in $IDS; do

        if  `echo ${ID} | egrep -q ${WHITE_IDS} ` ; then
            echo "whitelist.ignore.: ${ID}"
        else 
          echo "stop instance:${ID}"
          aws ec2 stop-instances --instance-ids ${ID}
          curl -X POST --data-urlencode "payload={\"text\": \"AWSステータス[${DSTR}]:起動中のインスタンスを停止しました(${ID})\"}" $TCR_URL
          ## レスポンスの出力用の改行
          echo ""
        fi
    done;
else
    if [ -z "$1" ] ; then
        echo "argument is required( --start / --stop ). nothing to do."
    else
        echo "argument is invalid. valid argument is --start or --stop."
    fi
fi

これで安心してAWS(EC2)を楽しみましょう!


停止の他に、自動起動や状態確認の処理を加えたサンプルをGithubに載せてます。
よかったら参考にしてください。

github.com

参考サイト:

dev.classmethod.jp

 

書いた人:飲み会大好き 内山

f:id:yasuaki-sakai:20170502104218j:plain