EventBridgeでRDSのsnapshot作成完了を検知する(Cloud Formation)

RDSのsnapshot作成の完了をEventBridgeで検知する処理をCloud Formationで実装していました。そこで一点ハマった箇所があったので共有です。

なおCloud Formationはやyaml形式で実装してます。

今回こちらの記事(Amazon RDSの各種イベントをEventBridgeで拾う時の話)を参考にさせていただき実装を着手しました

実際に検知できたコード

まず最終的にEventBridgeの検知が正常に動作したコードを貼っておきます

Type: AWS::Events::Rule
Properties: 
  Name: snapshot-created-event
  Description: Event snapshot is created
  EventPattern: >-
    {
     "source": ["aws.rds"],
     "detail-type": [
       "RDS DB Snapshot Event"
      ],
      "detail": {
        "EventID":["RDS-EVENT-0042", "RDS-EVENT-0091"]
      }
    }
  Targets:
     -
      Arn: 'arn:aws:lambda:ap-northeast-1:xxxxxxxxx:function:s3-lambda-func01'
      Id: StartLambda
     - 
      Arn: 'arn:aws:sns:ap-northeast-1:xxxxxxxxx:snapshot-notice'
      Id: EventNotice

以降、ハマった問題について記載しています

最初に試したこと

RDSのsnapshot作成が完了した時に手動実行時はRDS-EVENT-0042、自動実行時はRDS-EVENT-0091が発行されるようです。EventBridgeで検知するため、RDS-EVENT-0042RDS-EVENT-0091をEventIDの値に配列として定義しました。

RDSが発行するEventIDの種類については公式ドキュメントに詳しい内容が記載されていました。(公式ドキュメント)

下記が実装したコードです。

Type: AWS::Events::Rule
Properties: 
  Name: snapshot-created-event
  Description: Event snapshot is created
  EventPattern: 
    source:
      - "aws.rds"
    detail-type:
      - "RDS DB Snapshot Event"
    detail:
      EventID:
        - "RDS-EVENT-0042"
        - "RDS-EVENT-0091"
  Targets:
     -
      Arn: 'arn:aws:lambda:ap-northeast-1:xxxxxxxxx:function:s3-lambda-func01'
      Id: StartLambda
     - 
      Arn: 'arn:aws:sns:ap-northeast-1:xxxxxxxxx:snapshot-notice'
      Id: EventNotice
  • aws.rdsが発行した、detail-typeがRDS DB Snapshot Eventを検知する
  • RDS DB Snapshot EventのEventIDが”RDS-EVENT-0042″または”RDS-EVENT-0091″の場合に検知する
  • 検知した場合、lambda functionの実行とSNSへの通知を行う

検知ができない

上記のコードでsnapshot作成を実行し、完了するもEvent Bridgeは発火せず

色々記載方法を試しましたが解決しませんでした

jsonで実装

そしてなんとなくEventPatternの箇所のみjsonで記載すると検知ができました

  EventPattern: >-
    {
     "source": ["aws.rds"],
     "detail-type": [
       "RDS DB Snapshot Event"
      ],
      "detail": {
        "EventID":["RDS-EVENT-0042", "RDS-EVENT-0091"]
      }
    }

Cloud Formationのstackに登録されているjsonを確認

私はCloud Formation適用時にServerless Frameworkを使用しているため、sls packageコマンド(ymlをjsonに変換する)で出力されたjsonを比較してみました。

yamlで記載(検知できなかった方)

"EventPattern": {
     "source": [
       "aws.rds"
     ],
     "detail-type": [
       "RDS DB Snapshot Event"
     ],
     "detail": {
       "EventID": [
         "RDS-EVENT-0042",
         "RDS-EVENT-0091"
       ]
     }...

jsonで記載(検知できた方)

"EventPattern": "{\n \"source\": [\"aws.rds\"],\n \"detail-type\": [\n   \"RDS DB Snapshot Event\"\n  ],\n  \"detail\": {\n    \"EventID\":[\"RDS-EVENT-0042\", \"RDS-EVENT-0091\"]}\n}",
    "Targets": ....

jsonで記載した方は文字列そのままが出力されるため、結果的に同じなような。。。

ここで力尽きたので、とりあえず調査は諦めました

また後日詳しい原因がわかれば投稿します

(補足)snapshot名を絞り込むための指定方法

SourceIdentifierの項目で対象のsnapshot名を指定できます。snapshotが毎日作成されsnapshot名のsurfixに日付文字列などがくっつく場合があるので、prefixで先頭文字が一致するものを指定しています。

  EventPattern: >-
    {
     "source": ["aws.rds"],
     "detail-type": [
       "RDS DB Snapshot Event"
      ],
      "detail": {
        "EventID":["RDS-EVENT-0042", "RDS-EVENT-0091"],
        "SourceIdentifier": [{"prefix":"test"}]
      }
    }

このprefixなどについては公式ドキュメントを参考にしました

最後に

検証の検証するために毎回snapshotをマネージメントコンソールから実行し、完了を待っていました。ここで10分ほど時間がぽっかり空いてしまうのでもうちょっと良い手法を探します。どこかの記事でEvent Bridgeの検知テストを気軽に出来る方法を見たような気が。。。