ちょっと長いタイトルですが、そんなCDKコンストラクトライブラリをConstruct Hubに公開しました。
目次
概要
- HTTPCode_ELB_5XX_Countのうち、HTTPCode_ELB_[500|502|503|504]_Count以外のときに通知したい
- = 501,505,561などのときだけ通知する
- 500,502,503,504のときはそれぞれの具象ステータスのメトリクスで通知可能
- 500,502,503,504のときに5XXも通知されると重複になるため防ぎたい
- = 501,505,561などのときだけ通知する
これをCloudWatch複合アラーム(CompositeAlarm)によって(サプレッサーアラームという機能も使って)、上記のように「501,505,561などのときだけ通知する」ような、重複しない検知・通知の仕組みを実現することができました。
そしてその仕組みをCDKコンストラクトで作成し、Construct Hubで公開したというお話になります。
Construct Hub
Construct Hubとは、自作のAWS CDKコンストラクトをライブラリとして公開するところになります。
今回作ったものは「elb-other-5xx-alarm」という名前でConstruct Hubに公開しています。
また、Construct Hub公開のためには事前にnpmにpublishしている必要があり、npmパッケージとしてのページは以下になります。
ついでにGitHubもよければご覧ください。
事の流れ
以前こんな記事を書きました。
また、このネタを2023年5月のJAWS-UG SRE支部で発表しようとして再度検証したらうまくいく方法を見つけてしまったため、最終的には「うまくいった話」としてネタを更新しました。
そして今回、このネタをCDKで実現し、さらにそれをCDKのコンストラクトライブラリとしてConstruct Hubに公開してみました。
CloudWatch複合アラーム + サプレッサーアラーム
CloudWatch複合アラームは、複数のアラームの状態をもとに式で動的に判断できるアラームです。
HTTPCode_ELB_5XX_CountとHTTPCode_ELB_[500|502|503|504]_Countを以下のようなアラームルールで構成すれば、理論上[500|502|503|504]以外のときのみアラーム状態にできると考えました。
式通りに説明すると、「5XXが発火していて、[500|502|503|504]のどれも発火していない」ときに発火するルールです。
ALARM(HTTPCode_ELB_5XX_Count) AND ( NOT ( ALARM(HTTPCode_ELB_500_Count) OR ALARM(HTTPCode_ELB_502_Count) OR ALARM(HTTPCode_ELB_503_Count) OR ALARM(HTTPCode_ELB_504_Count) ) )
しかし実際、エラーの発生タイミングによって上記複合アラーム式がtrueになることもfalseになることもありうまくいきませんでした。(実際に500エラーの際は、上記複合アラームの評価タイミングより先に500かどうかわかっていないと式が成立せず、しかし500アラームが後から評価・発火されてしまって複合アラームの評価時点では「500は発火していない」という扱いになって、複合アラームが発火してしまった。)
そこで色々検証したところ、CloudWatch複合アラームの「サプレッサーアラーム」というものを用いることで解決することができました。
サプレッサーアラームとはCloudWatch複合アラームの機能の一つで、「サプレッサーアラームとして指定したアラームが発火している間は、複合アラームのアクションを抑制することができる機能」となります。(詳細は上記発表スライドをご覧ください)
つまり、サプレッサーアラームの発火を指定秒数待ち、その間は複合アラームを発火させない事で、複合アラームを遅延評価することができるという訳です。
これにより、上記で「500が発火するかどうか」を待ち切ってから複合アラームを評価することが可能になりました。
このように今回公開したCDKコンストラクトライブラリは、CloudWatch複合アラーム + サプレッサーアラームという組み合わせを用いて実現したものになります。
Constructの使い方
まず、CDKリポジトリでインストールします。
npm install elb-other-5xx-alarm
すると、使えるようになります。
import { ELBOther5XXAlarm } from 'elb-other-5xx-alarm'; new ELBOther5XXAlarm(this, 'ELBOther5XXAlarm', { alarmName: 'my-alarm', alarmActions: alarmActions, // e.g. [new SnsAction(new Topic(this, 'Topic', {}))] loadBalancerFullName: alb.loadBalancerFullName, // e.g. 'app/alb/123456789' period: Duration.seconds(60), threshold: 1, evaluationPeriods: 1, });
実際には以下のコードの感じで使います。
これはVPCなどに加えて、片方は501を、もう片方は503を固定レスポンスで返すような2つのELBとそれぞれの複合アラームが作成されます。デプロイ後にELBの発行するデフォルトエンドポイントにcurlなどで叩くと、片方のELBは501を返し、もう片方は503を返すというものになっています。
すると501を返すELBに紐付けた複合アラームの方はアクションを起こし、もう片方の503を返すELBに紐付けた複合アラームの方(発火させたくない)は一時的にアラーム状態にはなるがアクションは抑制されて発火せず、そのまますぐOK状態に戻ることがCloudWatchアラームコンソールなどで確認できます。
最後に
中々ニッチなコンストラクトですが、自分が欲しかったのと、Construct Hubに公開するいい機会だなと思いやってみました。
今回はSREネタの登壇を通して最終的にCDKネタに持っていくというCDKユーザーっぷりを見せることができました。