2015年4月15日水曜日

AWS EC2インスタンス起動・停止自動化によるコストの最適化【API利用編】

みなさんこんにちは。
鷲尾です。

本日は、短期集中連載企画の第2回目【API利用編】となります。


前回までのあらすじ

● ローカル環境に Amazon EC2 API Toolsを導入
● インスタンスの操作に必要となる情報を収集し、環境変数を設定するバッチファイルを作成
● 作成したバッチファイルとec2ver”コマンドでAmazon EC2 API Toolsが利用できることを確認

今回は「API利用編」ということで、インスタンスのステータスの確認、インスタンスの起動・停止が行えることを確認し、最終的に起動・停止用のバッチファイルの作成・実行まで行っていきます。

※なお、コマンドは各環境変数に値がセットされていないと実行することが出来ないため、ここでは、前回作成した環境変数設定バッチ(envSetup.bat)を実行した状態(環境変数に値がセットされている状態)であることを前提としています。

6.インスタンスのステータス確認
先ずは、ターゲットとするインスタンスIDの操作が行えることを確認するために、特定インスタンスのステータスを取得します。

ステータスを確認する場合は、以下のコマンドを使用します。
ec2-describe-instances インスタンスID


コマンドを投入したときの表示は以下のような表示となります。
■起動時



ここまでくれば、もうAPIでの起動・停止ができたも同然です!



7.インスタンスのStartStop
次は、いよいよインスタンスの起動・停止を制御してみます。
それでは、停止状態にあるインスタンスを再起動(Start)させてみましょう。

再起動させる場合は、以下のコマンドを使用します。
ec2-start-instances インスタンスID                                                                    


startコマンド投入サンプル

      ※ i-XXXXXXXXには、実在するインスタンスIDを指定してください


今度は、起動しているインスタンスを停止(Stop)させてみます。
停止させる場合は、以下のコマンドを使用します。

 
ec2-stop-instances インスタンスID       

stopコマンド投入サンプル


これで、APIからインスタンスの起動・停止が行えるようになりました!


なお、起動・停止用のAPIは、非同期処理となっています。このため、ec2-start-instances /ec2-stop-instances から処理が戻された時点で、指定したインスタンスの起動・停止は完了していません。
このため、ec2-start-instancesec2-stop-instancesを利用した場合、正しく起動・停止したかは、前述のec2-describe-instancesコマンドなどを利用して確認する必要があります。






8.Elastic IPアドレスの関連付け(EC2 Classicの場合のみ)
EC2(Classic)では、インスタンスを停止するとその時点で、インスタンスとElastic IPの関連付けが解除されてしまいます。
このため、停止・起動の自動化を行う場合、インスタンス再起動後に再度Elastic IPの関連付けを行う必要があります。
Elastic IPの関連付けには、以下のコマンドを使用します。
ec2-associate-address -i インスタンスID Elastic IP

Amzon EC2 VPCの場合は、インスタンスを停止してもElastic IPアドレスは開放されません。




9.起動・停止用バッチファイルを作成・実行してみる
インスタンスを起動・停止するためのバッチファイルを作成します。
ここでは、起動および停止バッチをインスタンス毎に作成しないよう、1つのバッチファイルを共用する前提でバッチファイルのパラメータを定義します。

【起動バッチ : ec2start.bat】

起動バッチのサンプルはこちらからダウンロード出来ます。
作成するバッチの概要は以下のとおりです。
パラメータ
1つのバッチファイルで複数のEC2インスタンスを起動するバッチとするため、パラメータを3つ用意します。
1パラメータ : リージョンコード (必須)
2パラメータ : インスタンスID  (必須)
3パラメータ : Elastic IP     (任意)

EC2 Classic環境で、Elastic IPアドレスの関連付けをする前提としているため第3パラメータを用意していますが、EC2 VPCであれば停止後にインスタンスとElastic IPアドレスとの関連付けが解除されないので第3パラメータは不要です。

◆リターンコード
  0 : インスタンスの起動に成功した
  1 : 起動しようとしたインスタンスIDが既に起動しているため、処理を中止した
  4  必須パラメータが入力されてない
  8  インスタンスへの接続に失敗した
12  Elastic IPアドレスの関連付けに失敗した(起動バッチのみ)
16 :インスタンスの起動に失敗 した

第3回の自動化編では、リターンコードが0、もしくは1であれば正常とみなすように設定します。
したがって、リターンコードが4以上だった場合は、異常終了となり、A-AUTO 50のクライアント画面にアラートが表示されます。

 
◆処理概要
1.パラメータの数をチェック
2.起動するインスタンスIDが停止中かチェック(※1
3.停止中であれば、インスタンスの起動指示を行う
4.30秒間隔でインスタンスが起動したかどうかをチェック(※1
  サンプルでは、30秒(※2)間隔で×3回チェックし、それでも起動中にならなければ起動失敗としています。
  なお、インターバルとリトライする回数はお客様の環境にあわせて設定してください。
5.インスタンスとElastic IPの関連付け
※ バッチファイルの詳細は、サンプルを用意していますので、そちらをご参照ください。


1 インスタンスが停止中か起動中かの判断は、ec2-describe-instances APIの --filterパラメータと中間ファイルを利用して判断する仕様としています。
2 30秒のインターバルは、A-AUTO 50binディレクトリに用意しているsleep.exe(指定時間sleepするモジュール(秒)を使用しています。このためA-AUTO 50が導入されている環境が前提となります。


sleep.exe を利用して実際にインスタンスの起動・停止を試してみる場合は、Amazon EC2 API ToolsとA-AUTO 50が必要となります。
A-AUTO 50のインストールはコミュニティサイトから基本ライセンスをダウンロードし、基本ライセンスインストール手順に従ってインストールしてください。
 

ec2start.bat
@echo off
rem input parameters
rem %1 region code
rem %2 instance id
rem %3 elastic ip (optional)


set EC2_HOME=XXXXXXXXXXXXXXXXXXX
set PATH=%PATH%;%EC2_HOME%\bin
set EC2_URL=https://ec2.%1.amazonaws.com
set JAVA_HOME=XXXXXXXXXXXXXXXXXXX
set AWS_ACCESS_KEY=
XXXXXXXXXXXXXXXXXXX

set AWS_SECRET_KEY=XXXXXXXXXXXXXXXXXXX
set INSTANCE_ID=%2
set ELASTIC_IP=%3
set PADDING_TIME=%time: =0%
set TMP_FILE=%~dp0%2_%DATE:~-10,4%%DATE:~-5,2%%DATE:~-2%%PADDING_TIME:~0,2%%PADDING_TIME:~3,2%%PADDING_TIME:~6,2%%PADDING_TIME:~9,2%.txt

set RC=99
set CHECK_LOOP=3
set SLEEP_SEC=30

echo ### EC2 run batch started. region=%1,instace id=%2,elastic ip=%3.
echo;

if "%1"=="" (
goto PARAM_INVALID
)

if "%2"=="" (
goto PARAM_INVALID
)

echo ### check status before start
call ec2-describe-instances %INSTANCE_ID% --filter "instance-state-name=stopped"> %TMP_FILE%

IF NOT "%ERRORLEVEL%" == "0" (
goto ACCESS_ERROR
) ELSE (
type %TMP_FILE%|more
for %%A in (%TMP_FILE%) do if %%~zA == 0 (goto NOT_STOPPED) else (goto START)
)

:START
echo ### instance starting ...
call ec2-start-instances %INSTANCE_ID%

for /L %%L in (1,1,%CHECK_LOOP%) do (
  echo ### instance status check count=%%L.
  rem A-AUTO 50で提供しているsleepモジュールを使用。秒数を指定して実行する
  sleep %SLEEP_SEC%


  call ec2-describe-instances %INSTANCE_ID% --filter "instance-state-name=running"> %TMP_FILE%
  type %TMP_FILE%|more


  for %%A in (%TMP_FILE%) do if not %%~zA == 0 (goto START_SUCCESS)
  echo ### instance status was not running.
)


以下省略



◆手作業によるバッチの実行
それではA-AUTO 50と連携させる前に、手動でバッチファイルを実行して正しく動作することを確認してみましょう。

以下で紹介しているバッチ(ec2start.bat)は、今回インスタンスの起動に使用するバッチです。
はじめに、ファイルの先頭に環境変数の設定を行う部分があるので、以下4つの環境変数に設定する内容を、実際に実行する環境に合わせて書き換えてください。
 ・EC2_HOME
 ・JAVA_HOME
 ・AWS_ACCESS_KEY
 ・AWS_SECRET_KEY

 
なお、ここではバッチのファイル名に”ec2start.bat”と設定していますが、任意のファイル名にしたい場合は、拡張子を除くファイル名を8バイト以内になるように設定してください。
※ 9バイト以上のファイル名も指定可能ですが、別途設定が必要となるため、先ずは8バイト以内で進めてください。

正しい環境変数を設定したら、コマンドプロンプトでパラメータを渡して実行します。
バッチは、以下のように実行します。

Cドライブにec2start.batを配置して実行する場合




バッチが実行されると、パラメータの入力チェックや、接続先インスタンスのステータス確認などを順に実行していきます。



 バッチの実行が終了すると、以下の様なログが出力されます。
実行結果サンプル
### EC2 run batch started. region=ap-northeast-1,instace id=i-XXXXXXXX,elastic ip=XXX.XXX.XXX.XXX

### check status before start
RESERVATION    XXXXXXXX      690404241651    A-AUTO Free
INSTANCE        i- XXXXXXXX  ami-81294380                    stopped A-AUTO_FREE     0       [marketplace: eggbgx9svw4xhzs1omttdv29q]        t1.micro        2015-04-09T04:17:58+0000        ap-northeast-1c aki-44992845                    monitoring-disabled                                     ebs                             paravirtual     xen     140737625860047077      sg-cffae6ce     default false  
BLOCKDEVICE     /dev/sda        vol-067cd300    2014-08-07T01:51:32.000Z        false          
TAG     instance        i- XXXXXXXX      Name    [CentOS6.5]A-AUTO Free

### instance starting ...
INSTANCE             i- XXXXXXXX         stopped   pending
### instance status check count=1.
Sleep 30 Second

### instance status was not running.
### instance status check count=2.
Sleep 30 Second
RESERVATION     XXXXXXXX      XXXXXXXX   A-AUTO Free
INSTANCE        i-XXXXXXXX      ami-81294380    ec2-54-168-72-199.ap-northeast-1.compute.amazonaws.com  ip-10-121-18-147.ap-northeast-1.compute.internal        running A-AUTO_FREE     0       [marketplace: eggbgx9svw4xhzs1omttdv29q]        t1.micro        2015-04-09T05:14:51+0000        ap-northeast-1c aki-44992845                    monitoring-disabled     54.168.72.199   10.121.18.147                   ebs                             paravirtual     xen     140737625860047077      sg-cffae6ce     default false  
BLOCKDEVICE     /dev/sda        vol-067cd300    2014-08-07T01:51:32.000Z        false          
TAG     instance        i-XXXXXXXX      Name    [CentOS6.5]A-AUTO Free

### instance start successful.
### instance associate address starting ...
ADDRESS              XXXXXXXX       i-XXXXXXXX                                                     
### instance associate address successful.
### EC2 run batch ended(RC=0). region=ap-northeast-1,instace id=i-XXXXXXXX,elastic ip=XXX.XXX.XXX.XXX.



【停止バッチ : ec2stop.bat

停止バッチのサンプルはこちらからダウンロード出来ます。 
インスタンスを停止するバッチも同様に作成します。
※ 起動用バッチと基本的なインタフェースは同じですが、以下の点のみ異なります

◆パラメータ
  停止ではElastic IPアドレスを指定することが無いため、第3パラメータは用意しません

◆リターンコード
  停止ではElastic IPアドレスを指定することが無いため、リターンコードに12は返しません


バッチの基本的な流れは、起動バッチとほぼ同じです。
詳細は、サンプルのバッチをご覧ください。


※ バッチサンプルの拡張子は、".txt"となっています。ダウンロードしたバッチファイルを使用する際は、"ec2start.bat"にリネームしてご利用ください。



如何でしょう。バッチファイルを実行してインスタンスの起動・停止が行えるようになりましたか?
以上で「API利用編」は終了です。
次回は、いよいよいA-AUTO 50と連携させる「自動化編」へと続きますので、楽しみにしてください。


1 件のコメント:

  1. バッチのサンプルがダウンロードできないのですが・・・。

    返信削除