私と私の猫の他は誰でも隠し事を持っている

野良プログラマ発、日々のアウトプット

AWS SNS のメッセージ属性とフィルターで、配信をオプトイン・アウトする

運用中のシステムから、警報やエラーの類を AWS SNS 経由で関係者に通知するというユースケースは割とありがちだと思います。そんな時、内容の重要度等に応じて配信先を選択するにはどうしたら良いか? という件について。

結論から言うと、メッセージ送信の際に件名・本文の他に属性(この場合だと重要度)を付与してやり、当該トピックに登録されたサブスクリプションのフィルターポリシーの設定に従って通知をオン・オフする、というやり方になります。

docs.aws.amazon.com

例として、「警報(Warning)」と「エラー(Error)」の二種類を持つシステムアラートを、SNS トピック MySystemAlert から配信するものします。この配信に際して、サービス運用者 staff@abc.def にはエラーだけを、技術担当者 engineer@abc.def には両方を通知したい場合は、両者をトピックにサブスクリプション登録した後、フィルターポリシーを以下のように設定します。

サービス運用者 staff@abc.def

{
   "alert_level": ["error"]
}

技術担当者 engineer@abc.def

{
   "alert_level": ["warning", "error"]
}

あとはトピックへのメッセージ送信の際に、下記のようにメッセージ属性を付与してやれば OK。ここでは alert_level が error なので、両者のサブスクリプションに配信されることになります。

aws sns publish --topic-arn <トピック MySystemAlert の ARN> --subject 'エラーが発生しました!!' --message 'これはテストです。無視して下さい。' --message-attributes '{"alert_level":{"DataType":"String","StringValue":"error"}}'

尚、サブスクリプションが Lambda 関数の場合は、メッセージ属性はパラメタ event.Records[].Sns.MessageAttributes.<属性名>.Value からアクセスできるので、これを使ってより細かいコントロールも可能になりますね。