はじめに
稼働時間が限定されているEC2を監視していて、インスタンスを意図的に停止しているのにCloudWatchアラームが発報されてしまう、という経験はないでしょうか。
私も検証環境のEC2を夜間・休日に停止する運用をしていたところ、停止中のインスタンスに対して不要なアラームが発生していました。
そこで今回は、平日8:00~20:00の稼働時間帯のみ EC2のステータスチェックを監視するCloudWatchアラームを作成してみました。
同じような課題を抱えている方の参考になれば幸いです。
やりたかったこと
実現したかった動きは以下のとおりです。
| 時間帯 | 時刻 | EC2の状態 | アラーム |
|---|---|---|---|
| 監視時間内 | 平日 10:00 | 停止 | 発報 |
| 監視時間内 | 平日 10:00 | StatusCheckFailed = 1 | 発報 |
| 監視時間内 | 平日 10:00 | 正常 | OK |
| 監視時間外 | 平日 22:00 | 停止 | 発報しない |
| 監視時間外 | 土日 | 停止 | 発報しない |
平日8:00~20:00のみ監視し、それ以外の時間帯はアラームの対象外にする
使用するメトリクス
StatusCheckFailed
監視対象は、EC2の標準メトリクスである StatusCheckFailed です。
このメトリクスは、EC2の状態によって次の値になります。
| EC2の状態 | StatusCheckFailed |
|---|---|
| 正常 | 0 |
| ステータスチェック失敗 | 1 |
| 停止中 | データなし(NULL) |
課題:停止中はメトリクスが送られない
ここで問題になるのが、停止中はメトリクス自体が送信されないという点です。
そのままでは「停止している」ことを異常として検知できません。逆に、欠損データを一律に異常として扱うと、夜間や休日の停止中にもアラームが鳴ってしまいます。
そこで、CloudWatchの メトリクス演算(Metric Math) を使って、この2つの問題を解決します。
実装
全体の流れは次のとおりです。
m1(StatusCheckFailed)
└ e1 = FILL(m1, 1) … 欠損を「異常(1)」に補完
└ e2 = IF(時間帯, e1, 0) … 監視時間帯以外は「0」にする
└ アラーム:e2 >= 1
すべて、CloudWatchアラームの作成画面の中で設定できます。
Step1:監視対象のメトリクスを選択する
- CloudWatchコンソールの左メニューから「アラーム」→「すべてのアラーム」を開き、「アラームの作成」をクリックします。
- 「メトリクスの選択」をクリックします。
- 「EC2」→「インスタンス別メトリクス」の順に選択します。
- 検索欄にインスタンスIDを入力し、対象インスタンスの
StatusCheckFailedにチェックを入れます。
Step2:欠損を異常扱いにする数式を追加する(FILL)
- 同じ画面のまま、上部の「グラフ化したメトリクス」タブを選択します。
Step1で選んだメトリクスが、IDm1として表示されています。 -
m1の「統計」を「最大」、「期間」を「1分」に変更します。 - 「数式を追加」をクリックし、プルダウンから「空の式で始める」を選択します。
- 追加された行(ID
e1)の「詳細」欄に、次の式を入力して「適用」をクリックします。
FILL(m1, 1)
この式は、メトリクスが送られてこない時間帯(NULL)を 1 で補完します。
| ID | 内容 | 正常 | 異常 | 停止中 |
|---|---|---|---|---|
| m1 | EC2の StatusCheckFailed
|
0 | 1 | NULL |
| e1 | NULLを1で補完した値 | 0 | 1 | 1 |
これで、「メトリクスが来ない = 異常」 として扱えるようになります。
Step3:監視時間帯を制御する数式を追加する(DAY / HOUR)
- もう一度「数式を追加」→「空の式で始める」を選択します。
- 追加された行(ID
e2)の「詳細」欄に、次の式を入力して「適用」をクリックします。
IF(((DAY(e1) <= 5 AND HOUR(e1) < 11) OR ((DAY(e1) <= 4 OR DAY(e1) == 7) AND HOUR(e1) == 23)), e1, 0)
数式は、IDで別のメトリクスを参照しています。ID列が m1 / e1 / e2 になっていることを確認してください。違う場合は、IDを書き換えるか、式の中のIDを合わせてください。
ここからは、この式の中身を解説します。
ポイント①:DAY() / HOUR() はUTC基準
CloudWatchの DAY() と HOUR() は、UTC基準で値を返します。
DAY() が返す値と曜日の対応は次のとおりです。
| DAY() | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|
| 曜日(UTC) | 月 | 火 | 水 | 木 | 金 | 土 | 日 |
ポイント②:JSTをUTCに換算する
JSTはUTC+9時間なので、監視の開始時刻と終了時刻は次のように換算できます。
| JST | UTC |
|---|---|
| 8:00 | 前日 23:00 |
| 20:00 | 当日 11:00 |
そのため、「平日(月~金)の8:00~20:00(JST)」は、UTCでは次の2つの条件に分けて書く必要があります。
| 条件 | UTCでの範囲 | JSTでの範囲 |
|---|---|---|
DAY <= 5 AND HOUR < 11 |
月~金の 0:00~10:59 | 月~金の 9:00~19:59 |
(DAY <= 4 OR DAY == 7) AND HOUR == 23 |
日~木の 23:00~23:59 | 月~金の 8:00~8:59 |
この条件に当てはまる時間帯だけ e1 の値を返し、それ以外の時間帯は 0 を返します。
Step4:アラームの条件を設定する
- 「グラフ化したメトリクス」タブで、
e2の行の左端にあるラジオボタンを選択します。
アラームの判定対象はe2だけです。m1とe1は、計算の材料として使われます。 - 画面右下の「メトリクスの選択」をクリックします。
- 「条件」で、次のように設定します。
| 項目 | 設定値 |
|---|---|
| しきい値の種類 | 静的 |
| アラーム条件 | 以上(>=) |
| しきい値 | 1 |
| アラームを実行するデータポイント | 3/3 ※一時的な失敗やメトリクスの遅延による発報を防ぐため |
| 欠落データの処理 | 欠落データを不正 (しきい値を超えている)として処理 ※データが欠けた場合に、異常の見逃しを防ぐため |
Step5:通知先とアラーム名を設定して作成する
- 「通知」で、アラーム状態のときに通知するSNSトピックを指定し、「次へ」をクリックします。
- アラーム名と説明を入力し、「次へ」をクリックします。
例:ec2-statuscheck-weekday-0800-2000 - プレビュー画面で内容を確認し、「アラームの作成」をクリックします。
動作確認
ケース1:金曜10:00(JST)にEC2を停止
StatusCheckFailed が送られてこない
m1 = NULL
FILLで補完される
e1 = 1
時刻を判定する(10:00 JST → 金曜 01:00 UTC)
DAY(e1) = 5
HOUR(e1) = 1
監視時間帯の条件を満たすため、e1 の値がそのまま返ります。
e2 = 1
アラーム条件 e2 >= 1 を満たす
ケース2:水曜21:00(JST)にEC2を停止
StatusCheckFailed が送られてこない
m1 = NULL
FILLで補完される
e1 = 1
時刻を判定する(21:00 JST → 水曜 12:00 UTC)
DAY(e1) = 3
HOUR(e1) = 12
監視時間帯の条件を満たさないため、0 が返ります。
e2 = 0
アラーム条件 e2 >= 1 を満たさない
注意点
祝日は考慮されません
DAY() で判定できるのは曜日だけです。祝日に停止していると、平日扱いになってアラームが発報されます。
-
起動と停止のタイミング
- 3データポイント・1分間隔の設定のため、8:00の時点でステータスチェックが正常になっていないと、数分後にアラームが発報されます。
- EC2は起動してからステータスチェックが正常になるまで数分かかるため、7:50頃までには起動しておくことをおすすめします。
- 停止するのは20:00以降にしてください。
-
タイムゾーン
- 数式はUTC基準で書いています。
- JST以外のタイムゾーンで使う場合は、換算をやり直してください。
おわりに
営業時間内だけ利用するEC2環境では、StatusCheckFailed を単純に監視すると、停止中の扱いが課題になります。
今回はCloudWatchのメトリクス演算で、次の2つを組み合わせて対応しました。
- FILL による欠損データの補完
- DAY / HOUR による監視時間帯の制御
これにより、「平日8:00~20:00のみ死活監視するCloudWatchアラーム」 を実現できました。
Lambda や EventBridge を使わず、CloudWatchアラームだけで実装できるので、手軽に導入できるのもメリットです。
検証環境や、営業時間限定で稼働するEC2を監視する際の参考になれば幸いです。
BIPROGYグループの技術への取り組み
We Are Hiring!





