CloudWatch Application Signals で複数の異なるルックバックウィンドウを持つバーンレートアラームを組み合わせつつ CDK で実装してみる

CloudWatch Application Signals で複数の異なるルックバックウィンドウを持つバーンレートアラームを組み合わせつつ CDK で実装してみる

2026.02.16

概要

CloudWatch Application Signals を使うことで SLO の管理はもちろん、バーンレートアラームも設定することができます。

スクリーンショット 2026-02-07 12.39.55.png

この際、複数のルックバックウィンドウ (エラーバジェットを計算する期間) に基づくアラームを設定すると良いとされています。

複数のルックバックウィンドウにアラームを設定することで、短いウィンドウの急激なエラー率の上昇を早期に検知し、また、小さなエラー率の上昇が長期的に蓄積されてエラーバジェットを枯渇させるのを防ぐことができます。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-ServiceLevelObjectives.html#CloudWatch-ServiceLevelObjectives-burn

エラー率を計算する幅が異なるアラームを複数設定することで、長期的に見てジリジリとエラーバジェットが減っている状態も、短期的にエラーバジェットが大きく減っている状態もどちらも検知しやすくなります。
また、Google Site Reliability Engineering workbook で言及されているような、短い期間で大きくエラーバジェットが減っている場合のみ通知を行い、長期的に見てエラーバジェットを使い切るかもしれないくらいの状況ではチケット起票に留めるといった設計も採用できます。

Multiple burn rates allow you to adjust the alert to give appropriate priority based on how quickly you have to respond. If an issue will exhaust the error budget within hours or a few days, sending an active notification is appropriate. Otherwise, a ticket-based notification to address the alert the next working day is more appropriate.

エラーバジェットが枯渇する状況のみで通知し、優先度によって通知の仕方 (チケット起票、オンコール通知など) を分けるというのは言葉を見れば単純な気もしますが、きちんと設計しようとするとなかなか難しいですよね。
とりあえずは Google Site Reliability Engineering workbook で紹介されている手法をそのまま真似してみるのが良いだろうということで、今回は CloudWatch Application Signals で複数のルックバックウィンドウを持つアラームを組み合わせて実装してみます。
また、この際 CloudWatch アラームを多く作成する必要があるため、CDK を利用して効率化してみます。

エラーバジェットの計算について

SLO 計算のローリング間隔は 28 日とし、Google Site Reliability Engineering workbook で紹介されている、バーンレートアラームのしきい値をそのまま採用します。

ルックバックウィンドウ 消費されたエラーバジェット
1 時間 2%
6 時間 5%
3 日間 10%

バーンレートアラームのしきい値は下記のように計算可能です。

burn rate threshold = X% * SLO interval length / look-back window size

ルックバックウィンドウが 1 時間の際、アラームを設定すべきバーンレートは下記のように計算できます。

0.02 * 60 * 24 * 28 / 60 = 13.44

同様に、ルックバックウィンドウが 6 時間の場合は下記のようになります。

0.05 * 60 * 24 * 28 / 360 = 5.6

ルックバックウィンドウが 3 日間の場合は下記のようになります。

0.1 * 60 * 24 * 28 / 4320 ≒ 0.933

ここは切り良く 10% に拘らずにしきい値を 1 にしても良いかもしれませんね。
また、複数ウィンドウでアラームを設定すべきという話とは別に、ロングウィンドウとショートウィンドウの組み合わせでアラームを構成した方が良いという話があります。

さらに、複合アラームをロングウィンドウのバーンレートとショートウィンドウのバーンレート (ロングウィンドウの 1/12) に設定し、両方のバーンレートがしきい値を超えた場合にのみ通知を受け取ることができます。これにより、現在も発生している状況についてのみアラートを受け取ることができます。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch-ServiceLevelObjectives.html#CloudWatch-ServiceLevelObjectives-burn

同じしきい値でより短いルックバックウィンドウのアラームと組み合わせることで、正に今エラーバジェットが減っている状態でのみ通知するように設計するわけです。

error-rate.png

この場合、しきい値は長い方のウィンドウで計算したものを利用し、長い方のウィンドウで計算したバーンレートと短い方のウィンドウで計算したバーンレートの両方がしきい値を超えていた際にアラート状態とします。
短い方のルックバックウィンドウは長い方の 1/12 に設定することが多いようです。

A good guideline is to make the short window 1/12 the duration of the long window
https://sre.google/workbook/alerting-on-slos/

また、3 日で 10% のエラーバジェットを消費する状態は 28 日間でぎりぎりエラーバジェットを使い果たすかどうかのペースなので、即座の対応は不要と考えられます。
この場合は SSM OpsCenter にチケットを起票するだけに留め、その他の場合に Slack 通知を行うこととします。
以上の設計を踏まえて、今回は下記アラームを設定することとします。

ロングウィンドウ ショートウィンドウ バーンレートアラームのしきい値 アクション
1 時間 5 分 13.44 Slack 通知 + OpsCenter へのチケット起票
6 時間 30 分 5.6 Slack 通知 + OpsCenter へのチケット起票
3 日間 6 時間 0.933 OpsCenter へのチケット起票

やってみる

下記構成のアプリケーションを構築して、試してみます。

architecture-1.png

各種コード類は下記リポジトリに格納しています。

https://github.com/masutaro99/sample-ecs-app

Application Signals に関する設定は CDK で行っており、細かい内容はについてはこちらのブログも参照下さい。

https://dev.classmethod.jp/articles/cdk-cloudwatch-application-signals/

ちなみに、単純なバーンレートアラームはマネジメントコンソールから SLI を作成する際にも設定でき、エラーバジェット消費量からバーンレートアラームしきい値への変換も行ってくれます。

スクリーンショット 2026-02-13 0.47.19.png

とはいえ、今回のような複合アラームを構成するケースには CDK が向いていると思います。
ルックバックウィンドウとしきい値の違いで多くの CloudWatch アラームを作成する必要があり、CDK でループさせながら定義できると便利だからです。
特定パスの Availability を扱うアラームだけで下図のように 9 個必要なため、Latency も設定したり複数パスに設定したりするとマネジメントコンソールからの設定が面倒になることは容易に想像できます。

CDK の細かい実装について、説明していきます。
まず、しきい値の設定は最初にまとめて行います。
notificationpage と指定した場合は Slack 通知 + SSM OpcCenter 起票、ticket と指定した場合は SSM Ops Center 起票のみとします。

https://github.com/masutaro99/sample-ecs-app/blob/85d7b13d2cdf064f15117727270df677ebf5b400/packages/iac/lib/monitoring.ts#L10-L29

SLO 設定において利用するルックバックウィンドウを指定する必要があるので、重複を省いた一意のリストを生成します。
今回で言えば [5, 30, 60, 360, 4320] となります。

https://github.com/masutaro99/sample-ecs-app/blob/85d7b13d2cdf064f15117727270df677ebf5b400/packages/iac/lib/monitoring.ts#L31-L39

生成したリストを CfnServiceLevelObjective の burnRateConfigurations 属性に渡します。

https://github.com/masutaro99/sample-ecs-app/blob/85d7b13d2cdf064f15117727270df677ebf5b400/packages/iac/lib/monitoring.ts#L105

burnRateConfigurations の指定を行うことで CloudWatch メトリクスとしても扱えるようになり、CloudWatch のサービスページからも確認できるようになります。

スクリーンショット 2026-02-15 15.41.53-1.png

CloudWatch アラームは forEach でループさせて作成します。
ルックバックウィンドウとしきい値の組み合わせに対して 1 つ作成する必要があるため、子アラームの使いまわしはできず、愚直にアラームを作成していくことになります。

https://github.com/masutaro99/sample-ecs-app/blob/85d7b13d2cdf064f15117727270df677ebf5b400/packages/iac/lib/monitoring.ts#L109-L193

CDK も宣言的に書いた方が可読性が高くて望ましい場面が多いと思っていますが、このくらいであればそこまで読み辛く無いですし、アラームのセットを複製しやすくて良いと思います。
複合アラームがアラート状態になると、下記のような Slack 通知が実施されます。

slack1.png

slack2.png

OpsCenter へのチケット起票も上手く実施されました。

opscenter.png

最後に

Google Site Reliability Engineering workbook で紹介されているような、少し凝った SLO 管理を CloudWatch Application Signals で実装してみました。
CloudWatch アラームでも上手く複合アラームを利用することで PromQL や NRQL と同じように実装することができます。
ただし、大量の CloudWatch アラームを作成することになるので、上手く CDK などで効率化すると良いと思います。

この記事をシェアする

FacebookHatena blogX

関連記事