💭

dynamodb stream -> event bridge pipesで失敗した時にDLQにメッセージが届かない

2024/12/20に公開

初めに

dynamodb stream -> event bridge pipesからeventが飛んでこない問題が頻発。
DLQも設定したけどメッセージは飛んでこない。なんで!?

結論

MaximumRecordAgeInSeconds < DynamoDBストリームの保持期間 である必要がある

整理

デフォルトでパイプのMaximumRecordAgeInSecondsが無限となっている。
パイプはMaximumRecordAgeInSeconds経過後にポーリングを諦めてDLQに配信する。
一方でDynamoDBストリームは保持期間が24時間。
そもそもDLQ配信に進まないし、進んだとしてもDLQが配信される前にDynamoDBストリームは消える!

というこでMaximumRecordAgeInSecondsを設定したいが、残念ながらawsコンソールからは設定できないらしい。
こんな感じで設定する。

$ cat ddb.json
{
  "DynamoDBStreamParameters": {
      "MaximumRecordAgeInSeconds": 3600,
      "DeadLetterConfig": {
          "Arn": "DLQのARN"
      }
  }
}

$ aws pipes update-pipe --name パイプ名 --role-arn ロールARN --source-parameters file://ddb.json

なお、cdkならコードで指定もできる

// Create Pipe
new pipes.CfnPipe(this, `pipe-${name}`, {
    roleArn: pipeRole.roleArn,
    source: ddbTable.test!,
    sourceParameters: {
        dynamoDbStreamParameters: {
            startingPosition: 'LATEST',
            deadLetterConfig: {
                arn: deadLetterQueue.queueArn,
            },
            maximumRecordAgeInSeconds: 300, // pipeが処理を諦めてDLQにメッセージを送るまでの時間。デバッグ用で短く設定
        },
    },
    target: sqsQueue.queueArn,
})

参考ドキュメント

[1] UpdatePipeSourceDynamoDBStreamParameters - Contents - https://docs.aws.amazon.com/ja_jp/eventbridge/latest/pipes-reference/API_UpdatePipeSourceDynamoDBStreamParameters.html#API_UpdatePipeSourceDynamoDBStreamParameters_Contents
ーーー
MaximumRecordAgeInSeconds
(Streams only) Discard records older than the specified age. The default value is -1, which sets the maximum age to infinite. When the value is set to infinite, EventBridge never discards old records.

Type: Integer
Valid Range: Minimum value of -1. Maximum value of 604800.
Required: No
ーーー

[2] Amazon EventBridge Pipes error handling and troubleshooting - Pipe DLQ behavior - https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes-error-troubleshooting.html#eb-pipes-dlq-behavior
ーーー
If you specify a DeadLetterConfig for a pipe with a Kinesis or DynamoDB source, make sure that the MaximumRecordAgeInSeconds property on the pipe is less than the MaximumRecordAge of the source event. MaximumRecordAgeInSeconds controls when the pipe poller will give up on the event and deliver it to the DLQ and the MaximumRecordAge controls how long the message will be visible in the source stream before it gets deleted. Therefore, set MaximumRecordAgeInSeconds to a value that is less than the source MaximumRecordAge so that there's adequate time between when the event gets sent to the DLQ, and when it gets automatically deleted by the source for you to determine why the event went to the DLQ.
ーーー

[3] DynamoDB Streams の変更データキャプチャ - DynamoDB Streams のデータ保持期限 - https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/Streams.html#Streams.DataRetention
ーーー
DynamoDB Streams 内のすべてのデータは、24 時間保持されます。特定のテーブルの直近 24 時間のアクティビティを取得して分析できます。ただし、24 時間を超えたデータはすぐにトリミング (削除) される可能性があります。
ーーー

[4] update-pipe
https://docs.aws.amazon.com/cli/latest/reference/pipes/update-pipe.html
ーーー
Update an existing pipe. When you call UpdatePipe, EventBridge only the updates fields you have specified in the request; the rest remain unchanged. The exception to this is if you modify any AWS-service specific fields in the SourceParameters, EnrichmentParameters, or TargetParameters objects. for example, DynamoDBStreamParameters or EventBridgeEventBusParameters. EventBridge updates the fields in these objects atomically as one and overrides existing values. This is by design, and means that if you don't specify an optional field in one of these Parameters objects, EventBridge sets that field to its system-default value during the update.
ーーー

Discussion