EC2インスタンスを業務時間だけ自動起動する処理をAWS SDK for PHP 2で作成するで自動起動処理を作成した。しかし実行後に、ロードバランサーに接続しているインスタンスのステータスがOutOfServiceのままで接続できなかった。
- タグAUTO_RECONNECTを付けたロードバランサーに接続しているインスタンスを再接続させたい。
- 自動起動処理とは別のphpスクリプトにしておく。別々に実行できるように。
- 自動起動処理の後にこのスクリプトを実行する。crontabで適度に時間を離して実行。
- おもに開発環境のロードバランサーを再接続させる用途。接続している全インスタンスが再接続する。
いきなりプログラムをコピペする
reconnect_elb.php
<?php
// Include the SDK using the Composer autoloader
require 'vendor/autoload.php';
use Aws\ElasticLoadBalancing\ElasticLoadBalancingClient;
$today = date('Y-m-d H:i:s');
echo "---BEGIN--- Auto reconnect to LoadBalancer {$today}\n";
# ap-northeast-1 アジアパシフィック(東京)
# ap-southeast-1 アジアパシフィック (シンガポール)
# ap-southeast-2 アジアパシフィック(シドニー)
# eu-central-1 欧州 (フランクフルト)
# eu-west-1 欧州 (アイルランド)
# sa-east-1 南米(サンパウロ)
# us-east-1 US East (N. Virginia)
# us-west-1 米国西部(北カリフォルニア)
# us-west-2 米国西部(オレゴン)
# 処理実行するリージョン
# eu-central-1 欧州 (フランクフルト) ここは使用してないので外す
$regions =
[
'ap-northeast-1',
'ap-southeast-1',
'ap-southeast-2',
'eu-west-1',
'sa-east-1',
'us-east-1',
'us-west-1',
'us-west-2',
];
# 各リージョン毎に再接続処理を実行
$return = array_map('reconnect', $regions);
function reconnect($region)
{
# クライアント取得
$elb_client = ElasticLoadBalancingClient::factory(['region' => $region]);
# リージョンの全ELBの情報を取得
$all_elbs = $elb_client->describeLoadBalancers();
# 全ELBの名前を取得
$all_elb_names = $all_elbs->getPath('LoadBalancerDescriptions/*/LoadBalancerName');
# リージョンにELBが無いなら処理終了
if (empty($all_elb_names)) {
echo "No ELB in $region. No Reconnect Anything \n";
return;
}
# ELB毎の処理
foreach ($all_elb_names as $elb_name) {
# ELBの名前をキーにタグを取得
$tag_info = $elb_client->describeTags(
[
'LoadBalancerNames' => [$elb_name],
]
);
$tag_key = $tag_info->getPath('TagDescriptions/0/Tags/*/Key');
# ELBにAUTO_RECONNECTのタグが無かったら処理飛ばす
if (!(in_array('AUTO_RECONNECT', $tag_key))) {
echo "$region:$elb_name Not Reconnect. Not Tag.\n";
continue;
}
# 以下、AUTO_RECONNECTのタグが有るときの再接続処理
echo "$region:$elb_name Reconnect START!\n";
# ELBの名前をキーに詳細説明情報を取得
$elb_info = $elb_client->describeLoadBalancers(
[
'LoadBalancerNames' => [$elb_name],
]
);
# 接続している全インスタンスIDを配列で取得
$instance_ids = $elb_info->getPath('LoadBalancerDescriptions/0/Instances/*/InstanceId');
# インスタンスID毎にELBへ切断、接続をする。
foreach ($instance_ids as $instance_id) {
# 切断処理:elb_nameに接続しているinstance_idを切断する
$result_deregister = $elb_client->deregisterInstancesFromLoadBalancer([
'LoadBalancerName' => $elb_name,
'Instances' => [
[
'InstanceId' => $instance_id,
],
],
]);
# 接続処理:elb_nameにnstance_idを接続する
$result_reregister = $elb_client->registerInstancesWithLoadBalancer([
'LoadBalancerName' => $elb_name,
'Instances' => [
[
'InstanceId' => $instance_id,
],
],
]);
echo "$instance_id is reconnect to ELB:$elb_name\n";
}
}
}
echo "---END--- Auto reconnect to LoadBalancer\n";
実行
- タグAUTO_RECONNECTのロードバランサーに接続している全インスタンスを切断→再接続する。
- AUTO_RECONNECTがついていると実行。タグの値は何でもいい。
$ php reconnect_elb.php
---BEGIN--- Auto reconnect to LoadBalancer 2015-05-07 15:54:49
ap-northeast-1:ELB1 Not Reconnect. Not Tag.
ap-northeast-1:ELB2 Not Reconnect. Not Tag.
ap-southeast-2:ELB-no-tag Not Reconnect. Not Tag.
ap-southeast-2:ELB-test-reconnect-tag Reconnect START!
i-XXXXXXXX is reconnect to ELB:ELB-test-reconnect-tag
i-YYYYYYYY is reconnect to ELB:ELB-test-reconnect-tag
No ELB in eu-west-1. No Reconnect Anything
No ELB in sa-east-1. No Reconnect Anything
No ELB in us-east-1. No Reconnect Anything
No ELB in us-west-1. No Reconnect Anything
---END--- Auto reconnect to LoadBalancer
Crontabで1日一回 自動実行させる
crontab
SHELL=/bin/bash
# root PATHを設定
PATH=/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin:/opt/aws/bin
# mailを送信したくない時
MAILTO=""
AWS=/home/ec2-user/aws-php
# 時間はJSTかUSTかシステムに合わせる。今回はJST。 ログはmessageに吐き出す。
# EC2インスタンスを業務時間だけ自動起動する処理
27 8 * * 1-5 php $AWS/ec2_start.php 2>&1 | logger -t AWS_SDK_AUTO -p local0.info
# AWS ロードバランサーに接続しているインスタンスを切断、再接続する処理
31 8 * * 1-5 php $AWS/reconnect_elb.php 2>&1 | logger -t AWS_SDK_AUTO -p local0.info
# EC2インスタンスを毎日自動バックアップする処理
34 8 * * * php $AWS/create_image.php 2>&1 | logger -t AWS_SDK_AUTO -p local0.info