AWS CLI を使って ELB からインスタンスを deregister したり register したりするスクリプトを shell で書いてみた.ポイントは ELB の waiter 部分で,実際にインスタンスを deregister してもすぐには反映されないため,数秒間隔でチェックをするようにしている.
なお,deregister するときにまだ処理中のリクエストは切れてしまう可能性があるため,ELB の Connection Draining の設定を一度確認しておくと良いと思う.基本的には有効にしておいて問題は無さそう.
ドキュメント
AWS CLI Command Reference を見れば問題なく使えた.
ただ誤操作などを防ぎたいため,IAM ポリシーの設定は事前に行っておく必要がある.ELB の IAM ポリシーにハマった件は先週書いた.
aws_utils.sh
ある程度汎用的に書いた.
#!/bin/sh # ELB の状態を確認する間隔(秒) SLEEP=3 ####################################### # AWS CLI をチェックする ####################################### check_awscli() { if ! which aws >/dev/null; then echo 'awscli not found' exit 2 fi } ####################################### # ホスト名からインスタンス ID を取得する # Arguments: # $1 HOST NAME # Returns: # INSTANCE ID ####################################### get_instance_id() { instance_id=$(aws ec2 describe-instances --filter "Name=tag:Name,Values=$1" --query Reservations[].Instances[].InstanceId --output text) if [ -z "$instance_id" ]; then echo 'host not found' exit 2 fi echo ${instance_id} } ####################################### # インスタンスが ELB に反映されるまで待機する # Arguments: # $1 ELB NAME # $2 INSTANCE ID # $3 STATE (InService or OutOfService) ####################################### elb_waiter() { while : do # 状態(InService or OutOfService)を取得する state=$(aws elb describe-instance-health --load-balancer-name $1 --instances $2 --query InstanceStates[].State --output text) if [ "$3" = "${state}" ]; then echo " LoadBalancerName: $1 InstanceId: $2 State:$3" break else echo " LoadBalancerName: $1 InstanceId: $2 State:$state" fi sleep ${SLEEP} done } ####################################### # ELB からインスタンスを外す # Arguments: # $1 ELB NAME # $2 INSTANCE ID ####################################### elb_deregister() { aws elb deregister-instances-from-load-balancer --load-balancer-name $1 --instances $2 > /dev/null } ####################################### # ELB にインスタンスを付ける # Arguments: # $1 ELB NAME # $2 INSTANCE ID ####################################### elb_register() { aws elb register-instances-with-load-balancer --load-balancer-name $1 --instances $2 > /dev/null }
start.sh
呼び出し側のスクリプトは以下のように書ける.プロビジョンをしたり,デプロイをしたり,任意の処理が行えると思う.
#!/bin/sh # スクリプトをインポートする . ./aws_utils.sh # コマンドチェックと定数の設定 check_awscli ELB_NAME=sample_elb HOSTS=(web01 web02 web03) for host in ${HOSTS[@]} do # インスタンス ID を取得する INSTANCE_ID=$(get_instance_id ${host}) # OutOfService になるまで待機 echo " deregister : ${INSTANCE_ID}" elb_deregister ${ELB_NAME} ${INSTANCE_ID} elb_waiter ${ELB_NAME} ${INSTANCE_ID} 'OutOfService' # # ホストごとにデプロイなどを実行する # # InService になるまで待機 echo " register : ${INSTANCE_ID}" elb_register ${ELB_NAME} ${INSTANCE_ID} elb_waiter ${ELB_NAME} ${INSTANCE_ID} 'InService' done
実行すると,実際に waiter で10秒程度止まっていることがわかる.
deregister : i-xxxxxxxx LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:InService LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:InService LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:InService LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:InService LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:OutOfService register : i-xxxxxxxx LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:OutOfService LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:OutOfService LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:OutOfService LoadBalancerName: sample_elb InstanceId: i-xxxxxxxx State:InService
Google Shell Style Guide
スクリプトを書くときは,Google が公開してる Shell Style Guide を参考にしている.たかが shell って言う人もいるかもしれないけど,キレイに書きたいし,統一的にも書きたいし,結構よくまとまってると思うので良かったら是非!