Auto ScalingのLifeCycleHookがマネジメントコンソールから作成できるようになりました

2017.09.14

まいど、大阪の市田です。

Auto Scalingでは「LifeCycleHook」という機能を使って、インスタンスの起動/破棄時にユーザが処理をフックして独自のアクションを実行することが可能です。 この機能を使う時、これまではAPI、CLI、CloudFormationのいずれかを利用する必要がありましたが、今回のアップデートで登録と削除がマネジメントコンソールからできるようになりました。

AWS Developer Forums: Auto Scaling Lifecycle Hooks Enhancements

LifeCycleHookについては、下記を参考にしてもらえればと思います。

【新機能】Auto Scalingのインスタンス起動/破棄時に初期処理/終了処理を追加 – LifeCycleHook機能のご紹介

試してみた

早速試してみたいと思います。

Auto Scaling Groupの作成

まずはAuto Scaling Groupを作りましょう。特別な設定は不要なので普通に作ります。

01-make-asg

Auto Scaling Groupが作れたら、新しく追加された「Lifecycle Hooks」タブをクリックします。

02-lifecyclehook-tab

「Create Lifecycle Hook」をクリックして下さい。

03-create-lchook

今回はインスタンスがLaunchされた時のフックを作ります。Terminate時のフックも必要ならもう1つ作成して下さい。

04-setting-lchook

作成出来ました。

05-create-successfully

無事に作成できたらHookを通知できるようにします。上記の画面では、CloudWatch Eventsの利用が紹介されていたので、リンクにあるドキュメントに従って通知環境を作成します。

Auto Scaling ライフサイクルフック | CloudWatch イベント を使用した通知の受け取り

Lambda Funtionの作成

まずはLambda Functionの作成です。今回はサンプルにあるNode.jsのFunctionをトリガー無しで作成しました。

06-create-function

Function名は分かりやすく「lifecycle-hook」にしています。

07-configure-function

このFunctionはイベントだけを記録するものです。

console.log('Loading function');

exports.handler = function(event, context) {
console.log("AutoScalingEvent()");
console.log("Event data:\n" + JSON.stringify(event, null, 4));
context.succeed("...");
};

IAM Roleは適当なものを付けてください。

08-lambda-iam-role

Lambda Functionが作成できたらARNを控えておきましょう。後で使います。

15-lambda-arn

CloudWatch Eventsの設定

次にCloudWatch Eventsを設定していきたいと思います。 先程紹介したドキュメントではAWS CLIによる設定方法が記載されていましたが、マネジメントコンソールでも設定可能です。ここでは両方の方法をご紹介したいと思います。

マネジメントコンソールで設定する場合

最初は、マネジメントコンソールを使った設定方法についてです。CloudWatch Eventsの画面で「Create rule」をクリックします。

17-create-rules

Event Sourceの設定で「Service Name」「Auto Scaling」を選択します。

18-select-service-name

次に「Event Type」から「Instance Launch and Terminate」を選択してください。

19-select-eventtype

今回はインスタンスLaunch時のLifecycleイベントだけを対象にしたいので、「Specific instance event(s)」を選択してプルダウンから「EC2 Instance-launch Lifecycle Action」を指定します。

20-specific-event

次に、対象のオートスケーリンググループを指定してください。今回は対象のグループを指定しましたが、全てのグループを対象にする場合は「Any group name」を指定します。

21-specific-asg

次にターゲットを設定します。

22-add-targets

ターゲットの種類はLambda Functionを選択しましょう。

23-select-lambda

実行したいLambda Functionを選択します。先程作成したものを選んでください。

24-select-function

最後にルール名を入力して終わりです。今回は「lifecyclehook」としています。

25-create-rule

これで、CloudWatch Eventsに「lifecyclehook」というルールができました。

26-success-create-rule

AWS CLIで設定する場合

次は、AWS CLIでCloudWatch Eventsを設定する方法です。マネジメントコンソールで設定された場合はスキップして下さい。

最初にライフサイクルアクションのjsonファイルを作成します。これはAutoScalingでインスタンスがLaunchされるイベントを指定する為です。 今回は「lifecyclehook-launch.json」というファイル名で作成しました。

{
"source": [ "aws.autoscaling" ],
"detail-type": [ "EC2 Instance-launch Lifecycle Action" ]
}

jsonファイルが作成できたらイベントのソースを定義します。イベントの内容は上記で作成したjsonファイルの通りです。ちなみにルールの名前は「lifecyclefook」にしています。

$ aws events put-rule --name lifecyclefook --event-pattern file://lifecyclehook-launch.json --state ENABLED

コマンドを実行すると、ルールのARNが返ってくるのでこれを控えておきましょう。マネジメントコンソールからも確認できます。

{
"RuleArn": "arn:aws:events:ap-northeast-1:xxxxxxxxxxxx:rule/lifecyclefook"
}

16-cloudwatchevents-rules-arn

次に、Lambda Functionを呼び出すためのアクセス権限をCloudWatch EventsのRulesに付与してください。

$ aws lambda add-permission \
> --function-name lifecycle-hook \
> --statement-id lifecycle-hook-launch-event \
> --action 'lambda:InvokeFunction' \
> --principal events.amazonaws.com \
> --source-arn arn:aws:events:ap-northeast-1:xxxxxxxxxxxx:rule/lifecyclefook
  • function-name:先程作成したLambd Functionの名前を指定します。
  • source-arn:CloudWatch Eventsで作成したルールのARNです。

次にCloudWatch Eventsのターゲットを作成します。ターゲットは作成したLambda Functionなので、ARNには先程控えておいた関数のものを指定しましょう。

$ aws events put-targets --rule lifecyclefook \
> --targets Id=1,Arn=arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxx:function:lifecycle-hook

これでCloudWatch Eventsに「lifecyclefook」というルールができました。

09-cloudwatch-rules

設定どおり「インスタンスのLaunch」のイベントがトリガーになっています。

10-rules-sammary

実際に確認してみる

それでは、オートスケーリングを実際にスタートさせてみます。

11-change-asg-settings

オートスケーリングで起動したインスタンスが「Pending:Wait」になっていることが確認できます。この状態でSSHでサーバにログインして必要な処理を行うことになります。(今回は何もしませんが)

12-waiting-action

次に、CloudWatch Logsから「LifecycleActionToken」を確認してみましょう。{ $.detail.EC2InstanceId = "<インスタンスID>" }という形でフィルターするとトークンが記載されたログを抽出できます。

13-eventlog-filter

このトークンを用いて「Pending」を次の状態に進めます。

aws autoscaling complete-lifecycle-action \
> --lifecycle-hook-name lifecycle-hook-test \
> --auto-scaling-group-name \
> --lifecycle-action-token xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx \
> --lifecycle-action-result CONTINUE
  • lifecycle-hook-name:マネジメントコンソールで作成した時のライフサイクル名です。
  • auto-scaling-group-name:対象のオートスケーリンググループ名です。
  • lifecycle-action-token:CloudWatch Logsに出力される対象インスタンスのトークン(LifecycleActionToken)です。

コマンドを実行すると対象のインスタンスが「InService」になりました。

14-inservice

最後に

ユーザの処理が終わって次の状態に進める「CompleteLifecycleAction」は、上記で見た通りマネジメントコンソールでは出来ないので、CLI等を使う必要があります。 しかし、オートスケーリングの環境では基本的に自動処理を行うケースが多いと思いますので「CompleteLifecycleAction」の処理は自動化するのがいいですね。

以上です。