EC2 の Spot Instance はコストを抑えられる一方で、AWS 側の都合により中断されることがあります。
そのため、Spot Instance を本番やバッチ処理で使う場合は、中断前の通知を受け取って安全に終了処理を行う仕組み を入れておくのが重要です。
この記事では、EC2 の Spot Instance interruption notices を取得する方法を、できるだけわかりやすく整理します。
Spot Instance interruption notice とは
Spot Instance が停止・終了される前に、AWS から送られる通知です。
通常は 中断の約2分前 に通知されます。
この通知を使うことで、たとえば次のような処理ができます。
- 処理中データの保存
- graceful shutdown
- ECS / Kubernetes / 独自アプリの drain 処理
- ログやメトリクスの出力
- 別インスタンスへの切り替え
ただし、この通知は ベストエフォート です。
必ず毎回届く前提ではなく、通知が来なくても問題が起きない設計 にしておくことが大切です。
取得方法は2つある
Spot Instance interruption notice を取得する方法は、主に次の2つです。
1. インスタンス内で取得する
EC2 インスタンス自身が、インスタンスメタデータを確認して通知を受け取る方法です。
2. EventBridge で取得する
AWS のイベントとして受け取り、Lambda や SNS などに連携する方法です。
まずは全体像をざっくり整理すると、次のような使い分けになります。
| 方法 | 用途 |
|---|---|
| インスタンスメタデータ(IMDS) | そのインスタンス自身が終了前処理をしたい |
| EventBridge | 複数台をまとめて監視・通知・自動化したい |
1. インスタンス内で取得する方法(IMDS)
もっともシンプルなのは、EC2 インスタンスの中から Instance Metadata Service(IMDS) を確認する方法です。
Spot Instance では、以下のメタデータを参照できます。
/latest/meta-data/spot/instance-action
このエンドポイントにアクセスすると、Spot Instance に中断通知が来ている場合に内容が返ります。
まだ通知が来ていない場合は 404 になります。
AWS では、この確認を 5秒ごと に行うことが推奨されています。
返ってくる内容
通知が来ていると、たとえば次のような JSON が返ります。
{
"action": "terminate",
"time": "2017-09-18T08:22:00Z"
}
action には次のような値が入ります。
terminatestophibernate
IMDSv2 で取得する例
現在は IMDSv2 を使う構成が一般的なので、まずトークンを取得してからメタデータを参照します。
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/spot/instance-action
監視スクリプトの例
以下は、5秒ごとに interruption notice を確認し、通知が来たら処理を始める例です。
#!/usr/bin/env bash
set -euo pipefail
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
while true; do
if RESPONSE=$(curl -s -f \
-H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/spot/instance-action); then
echo "Spot interruption notice detected: $RESPONSE"
# ここで終了前処理を実行
# 例:
# - ワーカー停止
# - キュー処理の終了
# - データ保存
# - ログ出力
break
fi
sleep 5
done
この方法が向いているケース
この方法は、そのインスタンス自身が終了前処理をしたい場合 に向いています。
たとえば次のようなケースです。
- バッチ処理中に checkpoint を保存したい
- systemd サービスを安全停止したい
- コンテナやアプリケーションを graceful shutdown したい
- queue worker を停止して処理中ジョブを保護したい
つまり、即座にその場で反応したい処理 に向いています。
2. EventBridge で取得する方法
次に、AWS 全体のイベントとして Spot Instance interruption notice を受け取る方法です。
Spot Instance の中断通知は、Amazon EventBridge にイベントとして流れてきます。
イベント種別は次の通りです。
EC2 Spot Instance Interruption Warning
これを使うと、次のような連携ができます。
- Lambda を起動する
- SNS で通知する
- SQS に送る
- Step Functions で処理を分岐する
- 監視基盤に送る
EventBridge のイベントパターン
EventBridge ルールでは、次のようなイベントパターンを設定します。
{
"source": ["aws.ec2"],
"detail-type": ["EC2 Spot Instance Interruption Warning"]
}
イベントの例
実際には、次のようなイベントが届きます。
{
"version": "0",
"id": "12345678-1234-1234-1234-123456789012",
"detail-type": "EC2 Spot Instance Interruption Warning",
"source": "aws.ec2",
"account": "123456789012",
"time": "yyyy-mm-ddThh:mm:ssZ",
"region": "us-east-2",
"resources": [
"arn:aws:ec2:us-east-2a:instance/i-1234567890abcdef0"
],
"detail": {
"instance-id": "i-1234567890abcdef0",
"instance-action": "terminate"
}
}
このイベントの detail.instance-id を使えば、どのインスタンスに通知が来たのかを特定できます。
EventBridge ルールを CLI で作る例
aws events put-rule \
--name spot-interruption-rule \
--event-pattern '{
"source": ["aws.ec2"],
"detail-type": ["EC2 Spot Instance Interruption Warning"]
}'
このあと、ターゲットとして Lambda や SNS を設定すれば、通知を受けて自動処理できます。
この方法が向いているケース
EventBridge は、複数台の Spot Instance をまとめて監視したい場合 に向いています。
たとえば次のような用途です。
- Spot 中断を Slack やメールに通知したい
- Lambda で自動復旧処理をしたい
- 終了されたインスタンスの情報を記録したい
- Auto Scaling や独自運用ツールと連携したい
つまり、運用監視や自動化のハブ として使いやすい方法です。
どちらを使うべきか
結論としては、次のように考えるとわかりやすいです。
インスタンス自身が終了前処理をするなら IMDS
アプリケーション停止、checkpoint 保存、ワーカー停止など、そのマシンの中で完結する処理 に向いています。
運用側で集約したいなら EventBridge
複数台の監視、通知、Lambda 連携など、AWS 全体で処理したい場合 に向いています。
実運用では併用がおすすめ
実際には、どちらか一方だけでなく 併用 がわりと定番です。
たとえば次のように分けると扱いやすいです。
-
IMDS
インスタンス内で graceful shutdown やデータ保存を行う -
EventBridge
運用チームへの通知や記録、別システム連携を行う
この形にしておくと、アプリ側と運用側の両方で中断に備えられます。
注意点
1. 通知はベストエフォート
通知が来ないケースもあり得るので、Spot Instance を使うなら 途中終了されても壊れにくい設計 が前提です。
2. 通常は約2分前通知
多くのケースでは約2分前に通知されますが、その短い時間で終えられる処理にしておく必要があります。
3. hibernate は注意
hibernate の場合は通知が出ても、通常の「2分猶予」があるとは限りません。
復帰前提の設計かどうかを含めて考えておく必要があります。
4. termination-time より instance-action を使う
古い情報では spot/termination-time を使っている例もありますが、基本的には spot/instance-action を使うのが推奨 です。
まとめ
EC2 Spot Instance の interruption notice は、次の2つの方法で取得できます。
-
IMDS
インスタンス自身が通知を取得する方法 -
EventBridge
AWS イベントとして受け取り、通知や自動化に使う方法
シンプルに覚えるなら、次の認識で十分です。
- そのインスタンスで終了前処理をしたい → IMDS
- 運用監視や自動化に使いたい → EventBridge
- 本番では両方使うのがおすすめ
Spot Instance はコスト最適化にとても便利ですが、終了前提で設計しないと運用が不安定になります。
interruption notice をうまく使って、安全に止まれる仕組みを入れておくのがポイントです。
参考
- AWS EC2 Spot Instance interruption notices
- AWS EventBridge と EC2 Spot interruption warning