higehikiのブログ

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

AWS SDK for PHP を使って動的にオートスケールインスタンスのプライベートIPを抽出する

f:id:higehiki:20140416125608p:plain

オートスケールを設定して動的にインスタンスが増減する仕組みに対して、管理インスタンスからリクエストを動的に送るための方法を検討していました。

特定のAvailabilityZoneのみが対象だったので、正規表現でPrivateIPを取ってくるとかいうやっつけの方法で対応しておいたんですが、あまりにもイケてないので、インスタンスに付随するタグ情報を基にスクリプトを再実装しました。


<?php
/**
 * GET PrivateIP by EC2 Tags
 */

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

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

// AWS VPC 対象となるサブネットIDを設定して下さい。
define('SUBNET1', 'subnet-AAAAAAAAA');
define('SUBNET2', 'subnet-BBBBBBBBB');

// 抽出したいインスタンスのタグ(name)を指定して下さい。
define('TAG', 'TAGTAGTAGTAG');

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

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


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

$ec2 = new AwstarEc2();
// EC2インスタンスのプライベートIP一覧取得
$ipList = $ec2->getInstanceList();

var_dump($ipList);


/*
 * AwsClass
 */
class AwstarEc2{
    
    private static $client;
    
    /**
     * init
     * Aws\Ec2\Ec2Client にリージョンをセットして初期化
     */
    private static function init(){
        $config = array(
            'key'    => KEY,
            'secret' => SECRET,
            'region' => REGION,
        );
        self::$client = Ec2Client::factory($config);
    }
  
    /**
     * getInstanceList
     * 特定リージョンのインスタンス情報をフォーマットを指定して取得する
     * @param type $rsync_type
     * @return type
     */
    public static function getInstanceList(){
        self::init();

        // 対象EC2(runnning)の取得
        $response = self::$client->describeInstances(array(
            "Filter" => array(
                array("Name" => "instance-state-name", "Value" => "running")
            )
        ));
        
        $ipList = array();
        
        foreach ($response['Reservations'] as $instances_no=>$reservations){
            foreach ($reservations as $key=>$value){
                if($key=="Instances"){
                    foreach($value as $k=>$v){
                        if($v['State']['Code'] == STATUS_running){
                            foreach($v['Tags'] as $tag){
                                if($v['SubnetId'] == SUBNET1 || $v['SubnetId'] == SUBNET2){
                                    if($tag['Value'] == TAG){
                                        $ipList[] = $v['PrivateIpAddress'];
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        
        return $ipList;
    }
}


AWS SDK for PHP
http://docs.aws.amazon.com/aws-sdk-php/latest/index.html


基本的に何でもできるようにAPIが用意されてますから、使えばいいんですけど、用途に応じて、このふかーい配列をこねこねするのはめんどくさいですねー。

ちなみに、オートスケール時にタグを付ける方法がパッとわからなかったので、実際には、ちょっと違う使い方しています。