概要
Auto Scaling グループのインスタンスは、スケールインやヘルスチェックの失敗で、Auto Scaling の判断で終了されます。インスタンスの EBS にあるログやデータを終了前に S3 へコピーしたいのに、コピーが終わる前にインスタンスが消えてしまう、ということが起こります。
このとき使うのが ライフサイクルフック です。終了時のライフサイクルフックをグループに付けておくと、終了が決まったインスタンスはすぐには終了されず、Terminating:Wait という待機状態で止まります。その間にデータの退避などの処理を行い、終わったら complete-lifecycle-action で「終了を進めてよい」と知らせます。
この記事では、ライフサイクルフックの状態遷移、ハートビートタイムアウトとデフォルトの結果(CONTINUE / ABANDON)、待機中の処理の動かし方を整理します。実践では、Auto Scaling グループに終了時のライフサイクルフックを付けて台数を 0 に減らし、インスタンスが Terminating:Wait で待つことを確かめてから、CloudShell から complete-lifecycle-action を送って終了させます。

クラウドおさる当番を交代させるとき、いきなり帰らせると引き継ぎ帳が残らぬのでござる。「帰る前に一声かけてから」と決めておくのが、今日のライフサイクルフックでござるよ。
この記事のメリット
- 終了時のライフサイクルフックで、インスタンスが
Terminating:Waitに入る流れを説明できるようになる - ハートビートタイムアウトとデフォルトの結果(
CONTINUE/ABANDON)の意味が分かる complete-lifecycle-actionとrecord-lifecycle-action-heartbeatの使い分けが分かる- 「終了前に処理を済ませたい」要件に、終了保護などの別の機能ではなくライフサイクルフックを選ぶ理由が分かる
執筆者とキャラクター紹介
執筆者:土肥(とひ)
株式会社ジェニュインの代表であり元エンジニア。これまでオンプレミスと AWS 環境のインフラ業務を担当。AWS 認定資格の学習で得た知識を、ハンズオンとともに解説するのが得意。直近では新人の教育も行っており、これから技術を学ぶ方が納得できる解説を心がけています。基礎編・Cloud Practitioner の記事では、解説役としても登場します。


クラウドおさる



はじめましてでござる。弊猿はクラウドおさる。IT インフラが異常に発達した猿山から、雲に乗って地上の AWS を学びに降りてきたのでござる。



基礎編や Cloud Practitioner の記事では、とひさんに素朴な疑問をぶつける役でござるな。Security - Specialty などの記事では、要所でワンポイントや注意点をひとこと添えるでござる。



猿山にもデータセンターや監視当番があって、地上で起きることはだいたい猿山にも同じ仕組みがあるのでござる。例え話がつい猿山に寄るのは、弊猿の癖でござる。
技術解説
インスタンスのライフサイクルとフック
Auto Scaling グループのインスタンスは、起動から終了まで決まった状態をたどります。スケールイン(希望する容量の縮小、動的スケーリング、スケジュール)で終了するインスタンスが決まると、そのインスタンスは Terminating に移り、InService には戻れなくなります。
終了時のライフサイクルフック(ライフサイクルの移行が「インスタンスの終了」、autoscaling:EC2_INSTANCE_TERMINATING)があると、Terminating と Terminated の間に待機の状態が入ります。
| 状態 | 内容 |
|---|---|
InService | グループの一員として動いている |
Terminating | 終了が決まった。ロードバランサーを使っていれば、ここで登録が解除される |
Terminating:Wait | ライフサイクルフックの待機中。インスタンスはまだ動いていて、ここで終了前の処理を行う |
Terminating:Proceed | ライフサイクルアクションが完了し、終了に進む |
Terminated | 終了した |
起動時のライフサイクルフック(autoscaling:EC2_INSTANCE_LAUNCHING)もあり、こちらは Pending:Wait で待ってからソフトウェアの導入などを済ませ、InService に入れます。


ハートビートタイムアウトとデフォルトの結果
ライフサイクルフックには、待機をいつまで続けるかと、時間切れのときにどうするかを設定します。
| 設定 | 内容 |
|---|---|
| ハートビートのタイムアウト | 待機する時間。既定は 3600 秒(1 時間)。コンソールでは 30〜7200 秒で指定する。終了時のフックは、必要な処理に合わせた短い値(30〜120 秒)が推奨されている |
| デフォルトの結果 | タイムアウトしたときの結果。「続行(CONTINUE)」か「中止(ABANDON)」 |
| グローバルタイムアウト | ハートビートで延長しても、48 時間かハートビートタイムアウトの 100 倍の、短いほうを超えて待機することはできない |
CONTINUE と ABANDON の違いは、起動時と終了時で効き方が変わります。
| 結果 | 起動時のフック | 終了時のフック |
|---|---|---|
CONTINUE | インスタンスを InService にする | 残りのフックを続けたうえで終了する |
ABANDON | インスタンスを終了する | 残りのフックを止めて終了する |
既定では、終了時のフックはどちらの結果でもインスタンスは終了します。終了時のフックはベストエフォートで、タイムアウトや中止のときも、Auto Scaling はそのままインスタンスの終了に進みます。フックだけでは、終了そのものを取りやめることはできません。
なお、インスタンスライフサイクルポリシーで TerminateHookAbandon のときにインスタンスを保持するよう設定しておくと、ABANDON で完了したインスタンスは終了せずに保持状態へ移ります。保持されたインスタンスは手で調べたあと、TerminateInstanceInAutoScalingGroup で終了させます。



終了時のフックだけなら、ABANDON を返しても当番は帰ってしまうのでござる。「終了を止める」のではなく「帰る前に時間をもらう」仕組みだと覚えておくでござるぞ。
待機中の処理を動かす方法
ライフサイクルフック自体は、インスタンスを待たせるだけです。待機中に何をするかは自分で用意し、終わったらライフサイクルアクションを完了させます。
| 方法 | 内容 |
|---|---|
| EventBridge のルール | ライフサイクルアクションのイベント(終了時は EC2 Instance-terminate Lifecycle Action)を受けて、Lambda 関数や Systems Manager の Automation を動かす。推奨されている方法 |
| SNS・SQS・Lambda への通知 | フックの通知先にトピック・キュー・関数を指定し、受け取った側で処理する(SQS の FIFO キューは使えない) |
| インスタンス上のスクリプト | インスタンスメタデータの autoscaling/target-lifecycle-state(移行先の状態)をポーリングし、Terminated に向かっていると分かったら処理する |
処理が終わったら、次のどちらかの API を呼びます。
| API(CLI) | 用途 |
|---|---|
complete-lifecycle-action | 結果(CONTINUE / ABANDON)を返して待機を終える。インスタンス ID か、ライフサイクルアクショントークンで対象を指定する |
record-lifecycle-action-heartbeat | タイムアウトまでの時間を最初から数え直し、待機を延ばす。たとえばタイムアウト 1 時間で 30 分後に呼ぶと、合計 90 分待てる |



退避が長引きそうなら「まだ引き継ぎ中でござる」と一声(ハートビート)かければ、待ってもらえるのでござる。ただし声をかけ続けても、上限(グローバルタイムアウト)より先には延ばせぬでござるな。
似た機能との違い
「インスタンスが勝手に消えないようにしたい」という要件には、似た機能がいくつかあります。終了前に処理を済ませたいなら、ライフサイクルフックが目的に合います。
| 機能 | 何をするか | 終了前の処理に使えるか |
|---|---|---|
| ライフサイクルフック(終了時) | 終了の前に待機時間を作り、処理が終わったら終了を進める | 使える |
| インスタンスのスケールイン保護 | スケールインで終了されるインスタンスの候補から外す | 使えない。ヘルスチェックの失敗による置き換えは止めない |
EC2 の終了保護(DisableApiTermination) | コンソール・CLI・API からの手動の終了を拒否する | 使えない。Auto Scaling による終了は止めない。処理の時間を作る仕組みでもない |
| スタンバイ状態 | インスタンスを一時的にグループのサービスから外す | 使えない。手動でサービスから外す操作で、終了前の処理の時間を作る仕組みではない |
実践
Auto Scaling グループ soa-lifecycle-asg に、終了時のライフサイクルフック soa-terminate-hook を付けます。希望する容量を 0 に減らし、インスタンスが Terminating:Wait で待つことを確かめてから、CloudShell でハートビートと complete-lifecycle-action を送って終了させます。ここでは退避処理の代わりに、待機中のインスタンスの状態を確かめる操作を行います。
前提条件
- リージョン:
ap-northeast-1(東京) - 以下のリソースが作成済みであること
まだ用意していない場合は、「作り方の参考」の記事の手順で作れます。リソース名は、この記事の名前に読み替えてください。
| リソース種別 | リソース名 | 内容 | 作り方の参考 |
|---|---|---|---|
| 起動テンプレート | soa-lifecycle-template | Amazon Linux 2023・t3.micro | EC2 Auto Scaling で落ちても自動で戻る Web サーバーを作る |
| Auto Scaling グループ | soa-lifecycle-asg | soa-lab-vpc のパブリックサブネット(1a・1c)。最小 0・希望 1・最大 1。インスタンス 1 台が InService | 同上 ※ロードバランサーは付けない |
作成するリソース一覧
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| ライフサイクルフック | soa-terminate-hook | インスタンスの終了前に待機させる |
手順 1: 終了時のライフサイクルフックを作る
AWS マネジメントコンソールにログインし、リージョンが ap-northeast-1(東京)であることを確認します。上部の検索バーに EC2 と入力し、「EC2」を選択します。
左側ナビゲーションの「Auto Scaling」→「Auto Scaling グループ」を選択し、soa-lifecycle-asg を開きます。「インスタンス管理」タブを選択し、インスタンスが 1 台 InService になっていることを確認します。
同じタブの「ライフサイクルフック」のセクションで「ライフサイクルフックを作成する」をクリックし、以下を設定します。
- ライフサイクルフック名:
soa-terminate-hook - ライフサイクル移行: 「インスタンス終了」
- ハートビートタイムアウト:
600秒(既定値は 3600 秒。手順を確かめやすいよう短めにしています) - デフォルトの結果: 「CONTINUE」(既定値は ABANDON なので変更します)
その他の項目はデフォルトのままにして、「作成」をクリックします。


手順 2: 希望する容量を 0 にする
「詳細」タブを選択し、「グループの詳細」の「編集」をクリックします。
- 希望する容量:
0
最小容量・最大容量はそのままにして、「更新」をクリックします。グループのステータスが「容量の更新」になり、インスタンスを 1 台終了しようとします。
手順 3: Terminating:Wait で待っていることを確かめる
「インスタンス管理」タブを選択します。インスタンスの「ライフサイクル」が Terminating:Wait になっています(表示が変わらない場合は、更新ボタンで一覧を読み込み直します)。


左側ナビゲーションの「インスタンス」→「インスタンス」を開くと、このインスタンスはまだ「実行中」です。終了は決まっていますが、フックの待機中なので、インスタンス上で退避などの処理を動かせる状態です。
手順 4: CloudShell で待機中のインスタンスを確かめ、待機を延ばす
上部のツールバーの CloudShell アイコンをクリックして AWS CloudShell を開き、次のコマンドで待機中のインスタンスを確認します。
aws autoscaling describe-auto-scaling-instances \
--query "AutoScalingInstances[?AutoScalingGroupName=='soa-lifecycle-asg'].[InstanceId,LifecycleState]" \
--output tableインスタンス ID と、Terminating:Wait の状態が表示されます。表示されたインスタンス ID を変数に入れ、ハートビートを送って待機を延ばします。
INSTANCE_ID=<表示されたインスタンス ID>
aws autoscaling record-lifecycle-action-heartbeat \
--lifecycle-hook-name soa-terminate-hook \
--auto-scaling-group-name soa-lifecycle-asg \
--instance-id $INSTANCE_ID何も表示されなければ成功です。タイムアウトまでの 600 秒が、ここから数え直されます。





実際の運用では、ここで EBS のデータを S3 へコピーするのでござる。その処理を EventBridge から Lambda や Automation で動かせば、人が CloudShell に張り付かなくても済むでござるな。
手順 5: ライフサイクルアクションを完了する
退避が終わったものとして、complete-lifecycle-action で CONTINUE を返します。
aws autoscaling complete-lifecycle-action \
--lifecycle-action-result CONTINUE \
--lifecycle-hook-name soa-terminate-hook \
--auto-scaling-group-name soa-lifecycle-asg \
--instance-id $INSTANCE_ID続けて、状態を確認します。
aws autoscaling describe-auto-scaling-instances --instance-ids $INSTANCE_ID \
--query "AutoScalingInstances[].[InstanceId,LifecycleState]" --output tableTerminating:Proceed が表示されます(すでに終了していれば、何も表示されません)。
手順 6: 終了したことを確かめる
EC2 のコンソールに戻り、soa-lifecycle-asg の「アクティビティ」タブを選択します。「アクティビティ履歴」の最新の行で、インスタンスの終了(Terminating EC2 instance: i-...)のステータスが「成功」になっていることを確認します。開始時刻から終了時刻までの間が、フックで待機していた時間です。


「インスタンス管理」タブを開くと、インスタンスはグループから無くなっています。



「消える前に何かを済ませたい」と言われたら、待たせる仕組みと、済んだことを知らせる API の組み合わせを思い出すのでござる。終了保護のように、終了そのものを止めるものと取り違えぬようにするでござるな。
まとめ
| 困りごと | 使うもの |
|---|---|
| 終了前にログやデータを退避したい | 終了時のライフサイクルフック(Terminating:Wait で待つ) |
| 処理が終わったら終了を進めたい | complete-lifecycle-action(CONTINUE / ABANDON) |
| 処理がタイムアウトに間に合わない | record-lifecycle-action-heartbeat で待機を延ばす |
| 起動後、ソフトウェアの導入を終えてからサービスに入れたい | 起動時のライフサイクルフック(Pending:Wait) |
- 終了時のフックがあると、インスタンスは
Terminating→Terminating:Wait→Terminating:Proceed→Terminatedとたどる - ハートビートタイムアウトの既定は 1 時間。時間切れのときはデフォルトの結果(
CONTINUE/ABANDON)で進む - 既定では、終了時のフックは
CONTINUEでもABANDONでもインスタンスは終了する。ABANDONのときに保持したいなら、インスタンスライフサイクルポリシーを組み合わせる - 待機はハートビートで延ばせるが、48 時間かタイムアウトの 100 倍の短いほうが上限
- EC2 の終了保護(
DisableApiTermination)は Auto Scaling による終了を止めない。スケールイン保護も、終了前の処理の時間を作る仕組みではない
参照先
- Amazon EC2 Auto Scaling インスタンスのライフサイクル – Amazon EC2 Auto Scaling
- Amazon EC2 Auto Scaling のライフサイクルフック – Amazon EC2 Auto Scaling
- Auto Scaling グループにライフサイクル フックを追加する – Amazon EC2 Auto Scaling
- Auto Scaling グループでライフサイクルアクションを完了する – Amazon EC2 Auto Scaling
- ライフサイクルフックを Auto Scaling グループに追加するための準備 – Amazon EC2 Auto Scaling
- インスタンスメタデータを使用してターゲットライフサイクル状態を取得する – Amazon EC2 Auto Scaling
- インスタンスのスケールイン保護を使用してインスタンスの終了を制御する – Amazon EC2 Auto Scaling
- インスタンスライフサイクルポリシーを使用してインスタンスの保持を制御する – Amazon EC2 Auto Scaling













