Amazon EC2 Auto Scaling のライフサイクルフックを完了させる時の lifecycle-action-result とは
- この記事で書くこと / 書かないこと
- Amazon EC2 Auto Scaling のライフサイクルフック
- lifecycle-action-result について分からないこと
- 環境を用意
- インスタンスを Launchさせる時
- インスタンスを Terminate させる時
- まとめ
- 参考
この記事は DeNA 21新卒×22新卒内定者 Advent Calendar 2021 #DeNA21x22AdCal の23日目の記事です。
この記事で書くこと / 書かないこと
書くこと
- Amazon EC2 Auto Scaling のライフサイクルフックを完了させる AWS CLI コマンド
complete-lifecycle-action
のlifecycle-action-result
引数(CONTINUE / ABANDON)について- どのような挙動をするのか
- Launch / Terminate 時
- ライフサイクルアクションが1つ / 複数ある時
- どのような場面で指定すべきか
- どのような挙動をするのか
書かないこと
- Amazon EC2 Auto Scaling の基本動作など
Amazon EC2 Auto Scaling のライフサイクルフック
Amazon EC2 Auto Scalingでは ライフサイクルフックという仕組みが使える。ドキュメントには以下のように紹介されている。
Amazon EC2 Auto Scaling は、Auto Scaling グループにライフサイクルフックを追加する機能を提供します。これらのフックにより、Auto Scaling グループは Auto Scaling インスタンスライフサイクルのイベントを認識し、対応するライフサイクルイベントが発生したときにカスタムアクションを実行することを有効にします。
ドキュメントにある図*1が分かりやすい。
Pending:Wait
/Terminating:Wait
の間にやりたい処理を実行する- 処理が終わったら、ライフサイクルアクションを完了させる
Pending:Proceed
/Terminating: Proceed
に移行する- その後
InService
/Terminated
となる
というような流れである。Pending:Wait
時は プロビジョニングなどやるし、Terminating:Wait
時はログの収集などをやるだろうか。何かと便利。
lifecycle-action-result について分からないこと
先述した aws autoscaling complete-lifecycle-action
のオプションに lifecycle-action-result
というものがある。これに関してドキュメントにはこう書いてある。
lifecycle-action-result (string) The action for the group to take. This parameter can be either CONTINUE or ABANDON .
CONTINUE
と ABANDON
という値が取れることは分かった。しかし以下の 2点がよく分からない。
- どのような挙動をするのか?
- どのような場面で指定すべきか?
ドキュメントを漁ってみても、あまりめぼしい情報が出てこなかったので、手元のAmazon EC2 Auto Scaling 環境で実験してみることにした。
環境を用意
今回は以下の 4パターンにおける CONTINUE / ABANDON の挙動を確認する。
- EC2 インスタンスを Launch する時
- ライフサイクルフックが 1 つだけ作成されている時
- ライフサイクルフックが複数作成されている時
- EC2 インスタンスを Terminate する時
- ライフサイクルフックが 1 つだけ作成されている時
- ライフサイクルフックが複数作成されている時
上の挙動確認のために、 2つの AutoScalingGroupを用意した。
- ライフサイクルフックを Launch / Terminate 時のそれぞれ 1 つずつ作成した AutoScalingGroup
- ライフサイクルフックを Launch / Terminate 時のそれぞれ 2 つずつ作成した AutoScalingGroup
まず Auto Scaling の起動設定を作成。
❯ aws autoscaling create-launch-configuration \ --launch-configuration-name test-as-conf \ --image-id ami-xxxxx \ --security-groups sg-xxxxx \ --instance-type t2.micro
この起動設定からインスタンスを作成/削除する Auto Scaling グループを作成。上述した 2つの環境を設定にそれぞれ書いておく。
❯ vim test-asg.json { "AutoScalingGroupName": "test-asg", "LaunchConfigurationName": "test-as-conf", "LifecycleHookSpecificationList": [ { "LifecycleHookName": "launch-hook", "LifecycleTransition": "autoscaling:EC2_INSTANCE_LAUNCHING" }, { "LifecycleHookName": "terminate-hook", "LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING" } ], "MinSize": 1, "MaxSize": 1, "DesiredCapacity": 1, "VPCZoneIdentifier": "subnet-xxxxxx" } ❯ vim test-asg-multiple-hooks.json { "AutoScalingGroupName": "test-asg-multiple-hooks", "LaunchConfigurationName": "test-as-conf", "LifecycleHookSpecificationList": [ { "LifecycleHookName": "launch-hook-1", "LifecycleTransition": "autoscaling:EC2_INSTANCE_LAUNCHING" }, { "LifecycleHookName": "launch-hook-2", "LifecycleTransition": "autoscaling:EC2_INSTANCE_LAUNCHING" }, { "LifecycleHookName": "terminate-hook-1", "LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING" }, { "LifecycleHookName": "terminate-hook-2", "LifecycleTransition": "autoscaling:EC2_INSTANCE_TERMINATING" } ], "MinSize": 1, "MaxSize": 1, "DesiredCapacity": 1, "VPCZoneIdentifier": "subnet-xxxxxx" } ❯ aws autoscaling create-auto-scaling-group \ --cli-input-json file://./test-asg.json ❯ aws autoscaling create-auto-scaling-group \ --cli-input-json file://./test-asg-multiple-hooks.json
本来はこのライフサイクルフックに NotificationTargetARN
を指定することで、SQS にジョブをキューしたり、Lambda を呼び出したりして、実行したい処理を呼び出す。今回はライフサイクルフック完了を CLI から直接行うだけなので、特に通知先は指定しない。
インスタンスを Launchさせる時
以上の設定で、ライフサイクルフックが 1つの環境も複数の環境も共に、既にインスタンスが 1台立ち上がり、ライフサイクルフックの完了を待っている(Pending:Wait
) 状態になっている。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-01651d39583878c03", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Pending:Wait", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false } ❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg-multiple-hooks \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-06f48fba796571cbc", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Pending:Wait", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
CONTINUE
ライフサイクルフックが 1つの場合
lifecycle-action-result
に CONTINUE
を指定して、launch-hook
という名前で作成したライフサイクルフックを完了させてみる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "launch-hook" \ --auto-scaling-group-name test-asg \ --lifecycle-action-result CONTINUE \ --instance-id i-01651d39583878c03
インスタンスの状態を確認してみると LifecycleState
が InService
になっている。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-01651d39583878c03", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "InService", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
ライフサイクルフックが複数の場合
lifecycle-action-result
に CONTINUE
を指定して、2つのうちの 1つのライフサイクルフック(launch-hook-1
) 完了させてみる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "launch-hook-1" \ --auto-scaling-group-name test-asg-multiple-hooks \ --lifecycle-action-result CONTINUE \ --instance-id i-06f48fba796571cbc
インスタンスの状態を確認してみると、ライフサイクルフックが 1つの場合は InService
していたのに対して、まだ Pending:Wait
のままである。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg-multiple-hooks \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-06f48fba796571cbc", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Pending:Wait", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
では続いて、残りのもう 1つのライフサイクルフック(launch-hook-2
) を、同じく lifecycle-action-result
に CONTINUE
を指定して完了させてみる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "launch-hook-2" \ --auto-scaling-group-name test-asg-multiple-hooks \ --lifecycle-action-result CONTINUE \ --instance-id i-06f48fba796571cbc
すると、全てのライフサイクルフックが完了したので、LifecycleState
が InService
となる。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg-multiple-hooks \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-06f48fba796571cbc", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "InService", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
ABANDON
ライフサイクルフックが 1つの場合
今度は ABANDON
を指定してみる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "launch-hook" \ --auto-scaling-group-name test-asg \ --lifecycle-action-result ABANDON \ --instance-id i-06088732b011ec77c
インスタンスは Terminating:Wait
となって、InService
にはならない。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-06088732b011ec77c", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Wait", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
ライフサイクルフックが複数の場合
lifecycle-action-result
に ABANDON
を指定して、2つのうちの 1つのライフサイクルフック(launch-hook-1
) 完了させてみる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "launch-hook-1" \ --auto-scaling-group-name test-asg-multiple-hooks \ --lifecycle-action-result ABANDON \ --instance-id i-05f20b0925768e65a
ABANDON
が指定されたため、1つ目を完了させた時点で2つ目のライフサイクルフックは無視され、Terminating:Wait
となった。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg-multiple-hooks \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-05f20b0925768e65a", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Wait", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
インスタンスを Terminate させる時
勘の良い方はもう大体挙動が理解できたと思われるが、続いてインスタンスを Terminate させる時の挙動について確かめてみる。インスタンスは先ほどの実験の残りカスが Terminating:Wait
のまま待機しているので、それを利用する。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-078955cc41ee3f010", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Wait", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
CONTINUE
ライフサイクルフックが 1つの場合
lifecycle-action-result
に CONTINUE
を指定して、terminate-hook
という名前で作成したライフサイクルフックを完了させてみる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "terminate-hook" \ --auto-scaling-group-name test-asg \ --lifecycle-action-result CONTINUE \ --instance-id i-06088732b011ec77c
その後インスタンスを確認してみると、LifecycleState
が Terminateing:Proceed
となる。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-06088732b011ec77c", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Proceed", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
少し待てば完全に Terminate され、AutoScalingGroup からいなくなる。
ライフサイクルフックが複数の場合
lifecycle-action-result
に CONTINUE
を指定して、2つのうちの 1つのライフサイクルフック(terminate-hook-1
) 完了させてみる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "terminate-hook-1" \ --auto-scaling-group-name test-asg-multiple-hooks \ --lifecycle-action-result CONTINUE \ --instance-id i-05f20b0925768e65a
CONTINUE
したので、Terminate 時でも、もう1つのライフサイクルフックが完了するまで Terminating:Wait
のままである。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg-multiple-hooks \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-05f20b0925768e65a", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Wait", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
続いて2つ目(terminate-hook-2
)を完了させる。
aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "terminate-hook-2" \ --auto-scaling-group-name test-asg-multiple-hooks \ --lifecycle-action-result CONTINUE \ --instance-id i-05f20b0925768e65a
全てのライフサイクルフックが完了したので、Terminating:Proceed
となり、しばらくしたら LifecycleState
が Terminated
となる。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg-multiple-hooks \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-05f20b0925768e65a", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Proceed", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
ABANDON
ライフサイクルフックが 1つの場合
ABANDON
を指定して terminate-hook
を完了させる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "terminate-hook" \ --auto-scaling-group-name test-asg \ --lifecycle-action-result ABANDON \ --instance-id i-078955cc41ee3f010
Terminate させる時は、CONTINUE
と同じく、Terminating:Proceed
となる。 ABANDON
は 「中断」という意味だが、インスタンスを減らすことを中断するわけではない。
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-078955cc41ee3f010", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Proceed", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
ライフサイクルフックが 複数の場合
ABANDON
を指定して 2つのうちの 1つのライフサイクルフック(terminate-hook-1
) を完了させる。
❯ aws autoscaling complete-lifecycle-action \ --lifecycle-hook-name "terminate-hook-1" \ --auto-scaling-group-name test-asg-multiple-hooks \ --lifecycle-action-result ABANDON \ --instance-id i-0aa497f0729a2a0bf
❯ aws autoscaling describe-auto-scaling-groups \ --auto-scaling-group-name test-asg-multiple-hooks \ | jq ".AutoScalingGroups[].Instances[]" { "InstanceId": "i-0aa497f0729a2a0bf", "InstanceType": "t2.micro", "AvailabilityZone": "us-east-2a", "LifecycleState": "Terminating:Proceed", "HealthStatus": "Healthy", "LaunchConfigurationName": "test-autoscale", "ProtectedFromScaleIn": false }
こちらも Launch 時と同じく、複数のライフサイクルフックがあったとしても、ABANDON
を指定した場合はその他のライフサイクルフックは無視される。問答無用でインスタンスは Terminating:Proceed
へと移行し、やがて Terminated
となる。
まとめ
Amazon EC2 Auto Scaling のライフサイクルフックを完了させる時の lifecycle-action-result
の挙動について、実際にコマンドを打ちながら確認した。まとめると以下のような感じ。
CONTINUE | ABANDON | |
---|---|---|
Launch × 1つのライフサイクルフック | InService |
Terminated |
Launch × 複数のライフサイクルフック | インスタンスは他のライフサイクルフックが完了されるのを待つ → 全てのライフサイクルフックが完了すると InService |
Terminated |
Terminate × 1つのライフサイクルフック | Terminated |
Terminated |
Terminate × 複数のライフサイクルフック | インスタンスは他のライフサイクルフックが完了されるのを待つ → 全てのライフサイクルフックが完了すると Terminated |
Terminated |
CONTINUE
- ライフサイクルフックを次のステップに進める
- ライフサイクルフックが複数あるなら、残りのライフサイクルフックの結果を待つ
- 完了していないライフサイクルフックが無くなったら、
InService
/Terminated
になる
- フックした処理が成功した場合に指定することが多い
- ライフサイクルフックを次のステップに進める
ABANDON
それでは皆様もよい AutoScaling ライフを!