スポンサーリンク

AWSのEC2インスタンスを自動で起動する(改訂版)

昨日のエントリに早速の追加です。

実は、ElasticLoadBalancingを使っている場合、EC2インスタンスを停止すると再度起動しても「OutOfService」から復帰しないという現象が発生します。そこで、ElasticIPをAssociateした後に該当インスタンスを一旦ELBから切り離し、再度設定するという方法で復帰させることにしました。

<?php
	require 'AWSSDKforPHP/aws.phar';
	require_once '/etc/aws_ec2.config.inc.php';
	
	use Aws\Ec2\Ec2Client;
	use Aws\ElasticLoadBalancing\ElasticLoadBalancingClient;
	
	$instancelist = array(
		'Instance ID',
	);
	$instanceipaddress_map = array(
		'Instance ID' => 'ElasticIP',
	);
	$loadbalancername = 'Load Balancer Name';
	
	$ec2 = Ec2Client::factory($config);
	$elb = ElasticLoadBalancingClient::factory($config);
	
	// インスタンス起動処理
	foreach ($instancelist as $ins) {
		// インスタンスのステータスチェック
		$response = $ec2->describeInstances(
			array(
				'InstanceIds' => array($ins,),
			)
		);
		foreach ($response['Reservations'] as $instances_no => $reservations) {
			foreach ($reservations as $key => $value) {
				if ($key == "Instances") {
					foreach ($value as $k => $v) {
						if ($v['InstanceId'] == $ins) {
							$ins_status_name = $v['State']['Name'];
							if ($ins_status_name == "stopped") {
								// インスタンスの起動
								$res = $ec2->startInstances(
									array(
										'InstanceIds' => array($ins,),
									)
								);
							}
						}
					}
				}
			}
		}
	}
	
	// ElasticIP割当処理
	foreach ($instanceipaddress_map as $ins => $ip) {
		for ($i = 1; $i <= 10; $i++) {
			$associated = false;
			// インスタンスのステータスチェック
			$response = $ec2->describeInstances(
				array(
					'InstanceIds' => array($ins,),
				)
			);
			foreach ($response['Reservations'] as $instances_no => $reservations) {
				foreach ($reservations as $key => $value) {
					if ($key == "Instances") {
						foreach ($value as $k => $v) {
							if ($v['InstanceId'] == $ins) {
								$ins_status_name = $v['State']['Name'];
								if ($ins_status_name == "running") {
									// ElasticIPのステータスチェック
									$res = $ec2->describeAddresses(
										array(
											'PublicIps' => array($ip,),
										)
									);
									foreach ($res['Addresses'] as $addr_no => $addr) {
										if ($addr['PublicIp'] == $ip) {
											$exist = $addr['Domain'];
											$associationid = $addr['AssociationId'];
										}
									}
									if (!$associationid && ($exist == 'vpc')) {
										// ElasticIPの割当
										$r = $ec2->associateAddress(
											array(
												'InstanceId' => $ins,
												'PublicIp'   => $ip,
											)
										);
										if ($r['AssociationId']) {
											$associated = true;
										} else {
											$associated = false;
										}
									} elseif ($associationid && ($exist == 'vpc')) {
										$associated = true;
									}
									// ElasticLoadBalancing再設定処理
									for ($j = 1; $j <= 10; $j++) {
										$inservice = false;
										$inprogress = false;
										$health_res = $elb->describeInstanceHealth(
										 	array(
										 		'LoadBalancerName' => $loadbalancername,
										 		'Instances' => array(
										 			array(
														'InstanceId' => $ins,
													)
												)
											)
										);
										foreach ($health_res['InstanceStates'] as $ins_no => $inst_states) {
											if (($inst_states['InstanceId'] == $ins) && ($inst_states['State'] != 'InService') && !$inprogress) {
												// ElasticLoadBalancingからの削除
												$regist_res = $elb->deregisterInstancesFromLoadBalancer(
													array(
														'LoadBalancerName' => $loadbalancername,
														'Instances' => array(
															array(
																'InstanceId' => $ins,
															)
														)
													)
												);
												// ElasticLoadBalancingへの再設定
												$regist_res = $elb->registerInstancesWithLoadBalancer(
													array(
														'LoadBalancerName' => $loadbalancername,
														'Instances' => array(
															array(
																'InstanceId' => $ins,
															)
														)
													)
												);
												$inservice = false;
												$inprogress = true;
											} elseif (($inst_states['InstanceId'] == $ins) && ($inst_states['State'] == 'InService')) {
												$inservice = true;
												$inprogress = true;
											}
										}
										if ($inservice) {
											break;
										} else {
											sleep(15);
										}
									}
								}
							}
						}
					}
				}
			}
			if ($associated) {
				break;
			} else {
				sleep(15);
			}
		}
	}
?>

今回修正した部分はハイライトで示した部分になります。一旦、該当インスタンスを切り離してから再設定し、「InService」になるまで待つという処理になります。これで、自動停止→自動起動を行った場合でも完全に元の状態に戻すことが可能になります。

それにしても、ロードバランサでこんな現象が発生するとは思いませんでした。AWSの各サービスはちょっとクセがあるかもしれないですねぇ。

ちなみに、今回参考にしたサイトはこちらです。

コメント

タイトルとURLをコピーしました