ALB配下のEC2を半分ずつ切り離しながらシェル一撃でデプロイする
やりたいこと
ALBのTarget Group配下に複数のEC2インスタンスが登録されている。
インプレースなデプロイなど、ユーザに影響を与えないように半分ずつ切り離しながら処理したいことがある。
これをシェルを使って一撃で実施したい。(jenkinsで1クリックのイメージ)
処理の流れ
AWS CLIを使って、Target Groupから半分ずつ 切り離し -> デプロイ -> 再登録
を2度繰り返す。Target Groupは以下の通りステータス遷移するため、それぞれ待機する。
参考: ターゲットヘルスステータス
- deregister
healthy → draining → unused
- register
unused → initial → healthy
下準備
- 作業マシンにAWS CLIをインストール/セットアップ
- Target Groupのヘルスチェック閾値、登録遅延タイムアウト設定値の見直し
- デフォルト時間のままだと時間が長く、切り離しや再登録に時間がかかるので適切な値に変更(参考)
- EC2インスタンスにグループタグを付与
ステップ
- Aグループ切り離し(
unused
まで待機) - Aグループデプロイ
- Aグループ再登録(
healthy
まで待機) - Bグループ切り離し(
unused
まで待機) - Bグループデプロイ
- Bグループ再登録(
healthy
まで待機)
シェルの内容
target_group_arn="my_target_group_arn"
group_a_instance_ids=$(aws ec2 describe-instances --filter "Name=tag:deploy_group,Values=A" --query "Reservations[].Instances[].InstanceId" --output text)
group_b_instance_ids=$(aws ec2 describe-instances --filter "Name=tag:deploy_group,Values=B" --query "Reservations[].Instances[].InstanceId" --output text)
alb_waiter_function() {
while :
do
state=$(aws elbv2 describe-target-health --target-group-arn $1 --targets Id=$2 --query "TargetHealthDescriptions[].TargetHealth.State" --output text)
if [ "$3" = "${state}" ]; then
echo "InstanceId: $2 State:$3 wait break!"
break
else
echo "InstanceId: $2 State:$state keep waiting..."
fi
sleep 10
done
}
# 1. Aグループ切り離し
echo -n ${group_a_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 deregister-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_a_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'unused'; done
# 2. Aグループデプロイ実行 (tagかinstance_idを利用。例としてansibleを実行)
ansible-playbook -i ./inventory/ec2.py --limit "tag_deploy_group_A" -u foo --private-key='~/.ssh/hoge.pem' deploy.yml
# 3. Aグループ再登録
echo -n ${group_a_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 register-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_a_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'healthy'; done
# 4. Bグループ切り離し
echo -n ${group_b_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 deregister-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_b_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'unused'; done
# 5. Bグループデプロイ実行
ansible-playbook -i ./inventory/ec2.py --limit "tag_deploy_group_B" -u foo --private-key='~/.ssh/hoge.pem' deploy.yml
# 6. Bグループ再登録
echo -n ${group_b_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 register-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_b_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'healthy'; done
追記: 2019/11/20
target_group_arn="my_target_group_arn"
group_a_instance_ids=$(aws ec2 describe-instances --filter "Name=tag:deploy_group,Values=A" --query "Reservations[].Instances[].InstanceId" --output text)
group_b_instance_ids=$(aws ec2 describe-instances --filter "Name=tag:deploy_group,Values=B" --query "Reservations[].Instances[].InstanceId" --output text)
alb_waiter_function() {
while :
do
state=$(aws elbv2 describe-target-health --target-group-arn $1 --targets Id=$2 --query "TargetHealthDescriptions[].TargetHealth.State" --output text)
if [ "$3" = "${state}" ]; then
echo "InstanceId: $2 State:$3 wait break!"
break
else
echo "InstanceId: $2 State:$state keep waiting..."
fi
sleep 10
done
}
# 1. Aグループ切り離し
echo -n ${group_a_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 deregister-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_a_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'unused'; done
# 2. Aグループデプロイ実行 (tagかinstance_idを利用。例としてansibleを実行)
ansible-playbook -i ./inventory/ec2.py --limit "tag_deploy_group_A" -u foo --private-key='~/.ssh/hoge.pem' deploy.yml
# 3. Aグループ再登録
echo -n ${group_a_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 register-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_a_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'healthy'; done
# 4. Bグループ切り離し
echo -n ${group_b_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 deregister-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_b_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'unused'; done
# 5. Bグループデプロイ実行
ansible-playbook -i ./inventory/ec2.py --limit "tag_deploy_group_B" -u foo --private-key='~/.ssh/hoge.pem' deploy.yml
# 6. Bグループ再登録
echo -n ${group_b_instance_ids} | xargs -I {} -P 0 -d\\t aws elbv2 register-targets --target-group-arn ${target_group_arn} --targets Id={}
for instance_id in $(echo ${group_b_instance_ids}); do alb_waiter_function ${target_group_arn} ${instance_id} 'healthy'; done
この記事を書いた翌日にこんな機能が出た
Application Load Balancer simplifies deployments with support for weighted target groups
Author And Source
この問題について(ALB配下のEC2を半分ずつ切り離しながらシェル一撃でデプロイする), 我々は、より多くの情報をここで見つけました https://qiita.com/moikei/items/5a8c9f025614447194ed著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .