higehikiのブログ

iPhoneアプリ「ログ雀」の中の人です。

任意のタイミングでAMIを生成して、それをベースにインスタンスを作って、ELBにぶらさげるスクリプト

立て続けにAWSネタ。
オートスケールがどうしても使えない案件で、直前にAMIをコピーしてインスタンスを作る手動作業から解放されるため、スクリプトを組んでみました。

f:id:higehiki:20140416213942p:plain

SDKで何でも出来て本当に便利です。

ただ、作ったインスタンスを任意のタイミングで落としたいんですが、そのスクリプトを組む気力が残ってない…。

サンプルスクリプトは続きから。

<?php
/**
 * Schedule Scale
 */

//==============================================================
// 本番用設定
//==============================================================
// AWS SDK autoload.phpのPATHを指定して下さい・
define('AUTOROAD', '/home/ec2-user/vendor/autoload.php');

// AWS 接続情報を設定して下さい。
define('KEY' , 'XXXXXXXXXXX');
define('SECRET' , 'YYYYYYYYYYYYY');
define('REGION' , 'ap-northeast-1');
// 東京リージョン ap-northeast-1

// AWS AMIを作成する対象のインスタンスID
define('BASE_INSTANCE', 'i-aaaaaaaaa');
define('AMI_NAME', 'ScheduleScale_'.date('YmdHis'));
define('AMI_DESCRIPTION', 'BBBBBBBB_ForScheduleScale');
define('BASE_NOREBOOT', true);

// AWS インスタンス起動時オプション
define('KEY_PAIR', 'key');
define('SECURITY_GROUP', 'seckey');
define('INSTANCE_TYPE', 'm1.large');

// AWS ELB名
define('ELB_NAME', 'elb_name');


// ------------設定ココまで-------------

// AWS インスタンス ステータス
define('STATUS_running', 'running');

// AWS AMI ステータス
define('STATUS_available', 'available');
define('STATUS_pending', 'pending');

//==============================================================


require_once (AUTOROAD);
use Aws\Ec2\Ec2Client;
use Aws\ElasticLoadBalancing\ElasticLoadBalancingClient;

$ec2 = new AwstarEc2();

// AMI 作成
$imageId = $ec2->createAMI();

sleep(10);

// 生成AMIのステータスを監視 availableになったら次の処理へ
$amiStatus = '';
while (true){
    $amiInfo = $ec2->describeAMI($imageId);
    foreach ( $amiInfo as $k=>$r ) {
        if($k === 'Images'){
            $amiStatus = $r[0]['State'];
        }
    }
    if($amiStatus === STATUS_available){
        break;
    }
    sleep(20);
}

// インスタンス起動
$instanceInfo = $ec2->runInstance($imageId);

foreach ($instanceInfo as $k=>$v){
    if($k === 'Instances'){
        foreach ($v as $key=>$val){
            foreach ($val as $column=>$value){
                if($column === 'InstanceId'){
                    $instanceId = $value;
                }
            }
        }
    }
}

sleep(10);

// 起動インスタンスのステータスを監視 availableになったら次の処理へ
$instanceStatus = '';
while (true){
    $instanceStatus = $ec2->describeInstance($instanceId);
    if($instanceStatus === STATUS_running){
        break;
    }
    sleep(20);
}

echo $instanceId;
$ret = $ec2->joinLoadBalancer($instanceId);
var_dump($ret);

exit;





/*
 * AwsClass
 */
class AwstarEc2{
    
    private static $client;
    private static $elbclient;
    
    /**
     * init
     */
    private static function init(){
        $config = array(
            'key'    => KEY,
            'secret' => SECRET,
            'region' => REGION,
        );
        
        self::$client = Ec2Client::factory($config);
        self::$elbclient = ElasticLoadBalancingClient::factory($config);
    }
    
    /**
     * createAMI
     * Executes the CreateImage operation.
     */
    public static function createAMI()
    {
        self::init();
        
        $result = self::$client->createImage(array(
            'InstanceId'  => BASE_INSTANCE,
            'Name'        => AMI_NAME,
            'Description' => AMI_DESCRIPTION,
            'NoReboot'    => BASE_NOREBOOT,
        ));
        
        return $result['ImageId'];
    }
    
    /**
     * describeAMI
     * @param type $imageId
     */
    public static function describeAMI($imageId)
    {   
        $result = self::$client->describeImages(array(
            'ImageIds' => array($imageId),
        ));
        
        return $result;
    }
    
    /**
     * runInstance
     * @param type $imageId
     */
    public static function runInstance($imageId)
    {
        $options = array(
            'ImageId' => $imageId,
            'MinCount' => 1,
            'MaxCount' => 1,
            'KeyName' => KEY_PAIR,
            'SecurityGroups' => array(
                SECURITY_GROUP,
            ),
            'InstanceType' => INSTANCE_TYPE,
        );
        $result = self::$client->RunInstances($options);
        
        return $result;
    }
    
    /**
     * describeInstance
     * @param type $imageId
     */
    public static function describeInstance($instanceId)
    {   
        $result = self::$client->describeInstanceStatus(array(
            'InstanceIds' => array($instanceId),
        ));
                
        foreach ($result as $k=>$v){
            if ($k === 'InstanceStatuses') {
                foreach ($v as $key=>$val){
                    foreach ($val as $column=>$value){
                        if($column === 'InstanceState'){
                            $status = $value['Name'];
                        }
                    }
                }
            }
        }
        
        return $status;
    }
    
    /**
     * joinLoadBalancer
     * @param type $instanceId
     */
    public static function joinLoadBalancer($instanceId)
    {
        $result = self::$elbclient->registerInstancesWithLoadBalancer(array(
            'LoadBalancerName' => ELB_NAME,
            'Instances' => array(
                array(
                    'InstanceId' => $instanceId,
                ),
            ),
        ));
        
        return $result;
    }
}