EventBridgeルールが削除できない

2023/06/27に公開

EventBridgeルールが削除できない

背景

このようにリソース群をterraform destroyしたのですが、
EventBridgeルールだけ削除できませんでした。

$ terraform destroy
// 略
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 1m0s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 1m10s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 1m20s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 1m30s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 1m40s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 1m50s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 2m0s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 2m10s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 2m20s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 2m30s elapsed]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Still destroying... [id=spot-interruption-rule, 2m40s elapsed]
^C
Interrupt received.
Please wait for Terraform to exit or data loss may occur.
Gracefully shutting down...

Stopping operation...
╷
│ Error: deleting EventBridge Rule (spot-interruption-rule): ValidationException: Rule can't be deleted since it has targets.
│       status code: 400, request id: 0a9fe7a4-31c2-4352-b860-3d230f8be96f
│ 
│ 
╵
╷
│ Error: execution halted
│ 
│ 
╵
╷
│ Error: execution halted
$

コマンドが終了しないため、Ctrl + Cで強制停止しました。
stateを確認してもeventbridgeルールだけ残っています。

$ terraform state list
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule
$

エラーメッセージ

やはりこれがポイントでしょう。

│ Error: deleting EventBridge Rule (spot-interruption-rule): ValidationException: Rule can't be deleted since it has targets.
│       status code: 400, request id: 0a9fe7a4-31c2-4352-b860-3d230f8be96f

ターゲットが存在しているから削除できない!ということでしょうか。
ですが今回のターゲットであるLambdaはdestroyされています。

他にターゲットがある?

別のターゲットが紐付いていないか調べる

さっそくルールに紐づくターゲットを調べてみます。

$ aws events list-targets-by-rule --rule "spot-interruption-rule" | jq '.Targets[].Id'
"Idxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"

ターゲットがある!!!!!
IDにterraformとついてないので手動でターゲットを追加していたっぽいです。
こいつが原因みたいですね。

※筆者環境にてterraformで作成したEventBridgeルールのターゲットは、このようにIDの頭にterraformとついていました。

$ aws events list-targets-by-rule --rule "spot-interruption-rule" | jq '.Targets[].Id'
"terraform-xxxxxxxxxxxxxxxxxxxxxx"

削除する

ということで削除します。
コンソール上からは削除できなさそうなのでawscliでやります。

# ターゲットIDを調べる
$ aws events list-targets-by-rule --rule spot-interruption-rule

# ターゲットIDを指定して削除する
$ aws events remove-targets --rule spot-interruption-rule --ids "<TargetID>"

動作確認

無事削除できました。
やったね

$ terraform destroy
// 略
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Destroying... [id=spot-interruption-rule]
module.SpotInterruptionNotice.aws_cloudwatch_event_rule.spot-interruption-rule: Destruction complete after 1s

Destroy complete! Resources: 1 destroyed.

今回思い知ったこと?

EventBridgeルールを削除するにはターゲットをすべて削除する必要がある!!!

...
確かにそうですが...もっと大切なことがありそうです

今回思い知ったこと

今回の事象の原因はTerraformでインフラ管理する中で、手動で設定を加えたことです。
IaCと手動を混ぜるとこういったことが起こる可能性がある、ということでいい学びになりました。

※すべてをIaCで管理できればいいですが、手動でリソース作るのは楽ですよね...

参考資料

https://speakerdeck.com/yuki_kurono/iacyun-yong-sitemitegan-zita-su-qing-rasisatoantipatan?slide=14
https://dev.classmethod.jp/articles/akiba-aws-iac-failure-cases/#toc-9

Discussion