
【Terraform TIPS】EventBridgeのターゲットでリトライポリシーを設定する場合は、maximum_event_age_in_secondsを明示的に設定する必要があります
こんにちは!クラウド事業本部の吉田です。
Terraform使っていますか?
TerraformでEventBridgeのルール・ターゲットとスケジューラーを構築する機会があったのですが、
デプロイ時に思わないところでエラーがでたため、備忘録として残しておきたいと思います。
留意事項
TerraformとAWS Providerのバージョンは下記の通りです。
- Terraform
- 1.7.4
- AWS Provider
- 5.94.1
今後のバージョンによっては解消される可能性があります。
その点、ご留意ください。
結論
- EventBridgeのターゲットでリトライポリシーを設定する場合は、maximum_event_age_in_secondsを明示的に設定する必要がある
- 指定しなければ、「60秒以上で設定する必要がある」というエラーが発生する
- EventBridgeのスケジューラーでリトライポリシーを設定する場合は、maximum_event_age_in_secondsを明示的に設定しなくても問題はない
- ターゲットとスケジューラーで挙動が異なるのは、terraformの方でデフォルト値が設定されるかどうかという違いがあるため
背景
案件対応で、EventBridgeのルール・ターゲットとスケジューラーをTerraformで構築しました。
お客様からリトライ再試行の最大回数は指定があったものの、リトライ再試行の最大間隔は指定されませんでした。
そのため、デフォルト値(24時間)を設定するため、EventBridgeのルール・ターゲットとスケジューラー共にmaximum_event_age_in_secondsは明示的に設定しませんでした。
Terraformコードとしましては、下記のような形です。
resource "aws_scheduler_schedule" "scheduler" {
name = "scheduler"
(省略)
target {
(省略)
retry_policy {
maximum_retry_attempts = 2
}
}
}
# EventBridge Rule (S3イベント)
resource "aws_cloudwatch_event_rule" "s3_trigger" {
name = "s3-trigger-rule"
(省略)
}
resource "aws_cloudwatch_event_target" "s3_trigger" {
rule = aws_cloudwatch_event_rule.s3_trigger.name
(省略)
retry_policy {
maximum_retry_attempts = 2
}
}
terraform plan
の時には特に問題は発生しなかったので、その後terraform apply
を実行しました。
すると、スケジューラーの方は何も問題は発生しなかったのですが、ターゲットの作成に失敗し、terraform apply
が失敗しました。
エラー文は、以下の通りでした。
Error: creating EventBridge Target (XXXXXXX): operation error EventBridge: PutTargets, https response error StatusCode: 400, RequestID: XXXXXX, api error ValidationException: 1 validation error detected: Value '0' at 'targets.1.member.retryPolicy.maximumEventAgeInSeconds' failed to satisfy constraint: Member must have value greater than or equal to 60
ざっくり要約すると下記の通りです。
- ターゲットのリトライポリシーのmaximumEventAgeInSeconds(maximum_event_age_in_seconds)が、0で設定されている
- ターゲットのリトライポリシーのmaximumEventAgeInSeconds(maximum_event_age_in_seconds)は、60秒以上で設定する必要がある
原因は明白なので、リトライポリシーのmaximum_event_age_in_secondsを明示的に設定しました。
(ターゲットの方だけmaximum_event_age_in_secondsを設定するだけでは不恰好のため、スケジューラーの方にもmaximum_event_age_in_secondsを設定しました)
resource "aws_scheduler_schedule" "scheduler" {
name = "scheduler"
(省略)
target {
(省略)
retry_policy {
maximum_retry_attempts = 2
maximum_event_age_in_seconds = 600
}
}
}
# EventBridge Rule (S3イベント)
resource "aws_cloudwatch_event_rule" "s3_trigger" {
name = "s3-trigger-rule"
(省略)
}
resource "aws_cloudwatch_event_target" "s3_trigger" {
rule = aws_cloudwatch_event_rule.s3_trigger.name
(省略)
retry_policy {
maximum_retry_attempts = 2
maximum_event_age_in_seconds = 600
}
}
修正したところ、無事terraform apply
が通るようになりました。
想定原因
Terraformのドキュメントを確認した所、
スケジューラーのmaximum_event_age_in_secondsはデフォルト値が設定されるが、ターゲットのmaximum_event_age_in_secondsはデフォルト値が設定されないという違いがわかりました。
では、それぞれのドキュメントを比較してみます。
スケジューラーのドキュメントは、下記の通りです。
retry_policy Configuration Block
- maximum_event_age_in_seconds - (Optional) Maximum amount of time, in seconds, to continue to make retry attempts. Ranges from 60 to 86400 (default).
- maximum_retry_attempts - (Optional) Maximum number of retry attempts to make before the request fails. Ranges from 0 to 185 (default).
引用元:aws_scheduler_schedule | Resources | hashicorp/aws | Terraform | Terraform Registry
maximum_event_age_in_secondsを見ると、「Ranges from 60 to 86400 (default)」とありますね。
つまり、当初想定していた通り、明示的に指定しなければ86400(24時間)が設定されるという訳です。
では次に、ターゲットの方のドキュメントを見てみましょう。
retry_policy
- maximum_event_age_in_seconds - (Optional) The age in seconds to continue to make retry attempts.
- maximum_retry_attempts - (Optional) maximum number of retry attempts to make before the request fails
引用元:aws_cloudwatch_event_target | Resources | hashicorp/aws | Terraform | Terraform Registry
先ほどのスケジューラーと違い、デフォルト値の記載がありません。
terraform apply
実行時のエラー文から推測するに、ターゲットに関してはmaximum_event_age_in_secondsを明示的に設定しなければ「0」が設定される可能性があります。
そして、「0」が設定されると、maximumEventAgeInSecondsの設定範囲(60秒から86400秒)から外れるため、「60秒以上に設定してください」というエラーが発生すると考えられます。
最後に
今回は、TerraformでEventBridgeのリトライポリシーを設定する際に発生したエラーと、その解決方法について紹介しました。
ターゲットとスケジューラーで微妙に挙動が異なるという点は、ドキュメントをよく読まないと見落としがちな部分だと思います。
同じような問題に遭遇された方の参考になれば幸いです。
最後まで読んでいただき、ありがとうございました!
クラウド事業本部の吉田でした!