EC2の自動起動・停止用シェルスクリプトサンプル

2014.12.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

弊社年内の営業日も昨日(12/26)で終了し、冬休みモードに入りました。皆様はいかがな状況でしょうか。当ブログは年末年始もちょいちょいと更新して行く事になると思われますので、皆様も休暇モードでまったりと御覧頂けますと幸いです。

さて、AWS環境に於いてEC2を所定の時間に起動・または停止したいというケースは良くある事と思います。インスタンスタイプに拠っては起動しっ放しにしておくのも費用の面で回避したい...という場合も往々にしてある事でしょう。その際は起動・停止処理をOSの稼働スケジュールに組み込んで処理をOS任せにすると言うのが真っ先に思いつくアイデアになるかと思われます。

EC2の起動・停止操作については、大きく以下2つの方法があります。当エントリでは後者の参考になるような、簡易なスクリプトを作成してみたのでそのサンプルコードを備忘録として残しておきたいと思います。

  • 管理コンソールにログインし、GUIベースで起動・停止の操作を行う
  • AWS CLIやSDKを使って、所定の環境からCLIベース(コマンド実行)で起動・停止の操作を行う/必要に応じてcron(Linux系の場合)やタスクスケジューラ(Windows系の場合)に組み込み、自動稼働させる

こちらがそのサンプルコードとなります。21行目、31行目のAWS CLIコードをそのままcronに組み込む事でも処理上問題は全く無いのですが、シェル内で他の処理を行いつつEC2の停止・起動も行うケースを想定してシェルスクリプトとして起こしてみた次第です。先頭のリージョンとインスタンスIDを設定すれば使えるようになっています。引数は--start--stopのみ許可し、停止中の起動(./ec2control.sh --start、起動中の停止(./ec2control.sh --stop)以外の処理指示以外はログのみ出して何も処理しないような形としています。

ec2control.sh

#!/bin/sh

DEFAULT_REGION='us-east-1'
INSTANCE_ID='i-xxxxxxxx'
echo ""
echo "instance-id:["$INSTANCE_ID"]"

## 指定インスタンスのステータス確認(aws ec2 describe-instance-status)
INSTANCE_STATUS=`aws ec2 describe-instance-status --instance-ids $INSTANCE_ID --region $DEFAULT_REGION | jq -r '.InstanceStatuses[].InstanceState.Name'`
echo "instance-status:["$INSTANCE_STATUS"]"

## 指定EC2インスタンスの起動(aws ec2 start-instances).
if [ -n "$1" ] && [ $1 = '--start' ] ; then

    if [ -n "$INSTANCE_STATUS" ] && [ $INSTANCE_STATUS = 'running' ] ; then
        ## 稼働中であれば特に何もしない.
        echo "status is running. nothing to do."
    else
        ## 停止中であれば起動指示.
        echo "status is stopped."
        aws ec2 start-instances --instance-ids $INSTANCE_ID --region $DEFAULT_REGION
        echo "ec2 instance starting..." 
    fi

## 指定EC2インスタンスの停止(stop). 
elif [ -n "$1" ] && [ $1 = '--stop' ] ; then

    if [ -n "$INSTANCE_STATUS" ] && [ $INSTANCE_STATUS = 'running' ] ; then
        ## 稼働中であれば停止指示.
        echo "status is running."
        aws ec2 stop-instances --instance-ids $INSTANCE_ID --region $DEFAULT_REGION
        echo "ec2-instance stopping..."
    else
        ## 停止中であれば何もしない.
        echo "status is stopped. nothing to do."
    fi

## 引数無しの場合は何もしない.
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
echo ""

Amazon Linuxの場合、EC2に関する処理権限を持つIAM Roleを割り当てたインスタンス作成・起動後、jqをインストールした状態で、以下シェルスクリプトを利用する事が出来るかと思います。

ちなみに、IAM Roleに割り当てた権限で特に何も設定せずに動かせているのは以下の仕組みに拠るもののようです。aws configureや設定ファイルを用いて設定を行っていればそれが優先されますが、何もされない場合は最終的にIAM Rolesのクレデンシャル情報を見に行く、と言う流れになっているようです。

こういったスクリプトはWindows環境に於いても必要性があると思ってますので、別の機会にPowerShellベースのスクリプトもご紹介出来ればと思います。こちらからは以上です。