EventBridge で配信に失敗したイベントをデッドレターキューに入れてみる

記事タイトルとURLをコピーする

こんにちは。技術課の山本です。
EventBridge を使い、様々なイベントを起点にして、AWSサービス同士を接続することがよくあると思います。
後続のサービスにイベントを配信しようとして失敗することも、稀にあります。
本記事では、イベントの配信に失敗した時に、デッドレターキューにイベントの情報を入れる方法をご紹介します。

EventBridge で配信に失敗したイベントをデッドレターキューに入れてみる

ご紹介するのは公式ドキュメントの以下の内容になります。

ドキュメントを要約すると以下です。

  • イベントの配信に失敗する場合とは、ターゲットが存在しない場合や、ターゲットへのアクセス許可がない場合である。
  • イベントの配信に失敗した場合、EventBridge は24時間の間に185回、配信を再試行する。(再試行にはエクスポネンシャルバックオフのアルゴリズムを用いる。)
    • 上記はデフォルトで、利用者側でイベントの保持機関(最大24時間)やリトライ回数(最大185回)を変更可能。
  • 再試行全てに失敗した場合、イベントは削除となる。
    • 配信に失敗したイベントを残す際には、デッドレターキューを活用できる。

デッドレターキューに入る内容

  • RULE_ARN
    • EventBridgeルールのARN
  • TARGET_ARN
    • ターゲットリソースのARN
  • ERROR_CODE
    • エラーコード。以下は、DLQ が返す可能性のあるエラーコードのサンプルです。
      • NO_PERMISSIONS
        • ターゲットへのアクセス許可がない
      • NO_RESOURCE
        • ターゲットが存在しない
      • RESOURCE_ALREADY_EXISTS
        • 作成しようとしたリソースが既にある
      • THROTTLING
        • スロットリングした
      • TIMEOUT
        • タイムアウトした
  • ERROR_MESSAGE
    • エラーメッセージの内容
  • EXHAUSTED_RETRY_CONDITION
    • 使い切った再試行の状況。次の条件が返されることがあります。
      • MaximumRetryAttempts
        • 再試行回数の上限に達した場合
      • MaximumEventAgeInSeconds
        • イベントの保持期間を超えた場合
  • RETRY_ATTEMPTS
    • リトライした回数

デッドレターキューを使用する際の注意点

  • デッドレターキューは Amazon SQS の 標準キューとなる。FIFO キューを使用することはできない。
  • デッドレターキューは EventBridge のルールを作成するリージョンと同じリージョンに存在する必要がある。
  • AWSマネジメントコンソールを使用して、EventBridgeのスケジュールやルールにデッドレターキューを設定した場合、EventBridge から SQS キューへのアクセスを許可するリソースベースのポリシーが SQSキューにアタッチされます。
    • API などで作成する場合は以下を参考に、SQSキューにAccess policy 付与ください。
{
  "Sid": "Dead-letter queue permissions",
  "Effect": "Allow",
  "Principal": {
     "Service": "events.amazonaws.com"
  },
  "Action": "sqs:SendMessage",
  "Resource": "arn:aws:sqs:us-west-2:123456789012:MyEventDLQ",
  "Condition": {
    "ArnEquals": {
      "aws:SourceArn": "arn:aws:events:us-west-2:123456789012:rule/MyTestRule"
    }
  }
}

試してみる

失敗パターン1 ターゲットが存在しない場合(再試行の上限超過でエラーとなる)

Lambda を呼び出す EventBridge スケジュールの再試行回数を0回にして、イベントの保持期間を 1分にしてみます。

Lambda を削除した状態で、イベントを配信してみると、デッドレターキューの中身は以下のようになりました。
ERROR_CODE は ResourceNotFoundException 、EXHAUSTED_RETRY_CONDITION は MaximumRetryAttempts になっていました。

失敗パターン2 ターゲットが存在しない場合(イベントの保持期間が過ぎてエラーとなる)

Lambda を呼び出す EventBridge スケジュールの再試行回数を185回にして、イベントの保持期間を 1分にしてみます。

Lambda を削除した状態で、イベントを配信してみると、デッドレターキューの中身は以下のようになりました。
ERROR_CODE は ResourceNotFoundException 、EXHAUSTED_RETRY_CONDITION は MaximumEventAgeinSeconds になっていました。

失敗パターン3 ターゲットへのアクセス許可がない場合(イベントの保持期間が過ぎてエラーとなる)

Lambda を呼び出す EventBridge スケジュールの再試行回数を185回にして、イベントの保持期間を 1分にしてみます。

EventBridge の IAM ロールについているポリシーの権限を細工します。

イベントを配信してみると、デッドレターキューの中身は以下のようになりました。
ERROR_CODE は AccessDeniedException 、EXHAUSTED_RETRY_CONDITION は MaximumEventAgeinSeconds になっていました。

まとめ

Event Bridge でイベントの配信に失敗した時に、デッドレターキューにイベントの情報を入れる方法をご紹介しました。 SQS キューに入るので、後続でLambdaを呼び出して通知したりもできそうですね。

余談

去年と同じ2月11日に雪が降りました。
近くの山を散歩してきました。
雪景色は良いですね。

山本 哲也 (記事一覧)

カスタマーサクセス部のエンジニア(一応)

好きなサービス:ECS、ALB

趣味:トレラン、登山(たまに)