LoginSignup
0
0

More than 1 year has passed since last update.

EventBridgeのサンドボックスを使いイベントパターンのチェックを行う。

Last updated at Posted at 2022-11-22

はじめに

先日、EventBridgeCloudTrailに記録されたイベントを契機にするルールを作成した際、四苦八苦しながら少しだけサンドボックスの機能を使ってみたので、残しておこうと思います。

EventBridgeのサンドボックス機能とは

EventBridgeのルールを「イベントパターンを持つルール」の形式で作成する場合、各サービス等から出力されるイベントに合致するように「イベントパターン」を記載して、イベントに合致した場合にルールを実行する動作となりますが、「イベントパターン」の記載方法があっているかを確認するためには実際にイベントを発生させて確認する必要があります。

ただ、記載方法があっているかを確認するのに毎回イベントを発生させるのは非常に手間なので、2022年3月に新たに「サンドボックス」の機能が加わりました。

各サービスごとに用意されている「サンプルイベント」からサンプルを選択して、サンプルのイベントに対して、自分で作成した「イベントパターン」が合致するかを確認するか、もしくはイベント発生時に呼び出されるイベントオブジェクトをサンプルとして登録して、「イベントパターン」が合致するかを確認する方法があります。

  • サンプルイベントからサンプルを選択する場合
    Monosnap_20221120_194811.png

  • 自分でサンプルを作成する場合
    Monosnap_20221120_195016.png

今回やりたかったこと

今回EventBridgeで最終的にやりたかったこととしては、Fargateをブルーグリーンデプロイメントでデプロイ途中、デプロイを手動で停止した際のイベントを検知して通知することをやりたかったというのが本来の目的です。

Monosnap_20221120_200350.png

ただ、イベントパターンを作成する際に、イベントパターンの書式確認のため毎回Fargateのデプロイを実施するのは骨が折れるため、「サンドボックス」で書式があっていることを確認してみようと思います。

カスタムサンプルイベントの作成

元々用意されているサンプルイベントを使うのもよいですが、今回はCloudTrailに記録されるイベントを使いたかったので、カスタムでサンプルイベントを作成しようと思います。

ただ、CloudTrailに記録されるイベントの履歴は、実際にイベントが発生した際に呼び出されるイベントオブジェクトの書式と異なるようで、CloudTrailに記録されるJSON形式のイベント履歴をそのままサンドボックスのサンプルイベントにコピペしてチェックしても「サンプルイベントは無効です。」と出てしまい、チェックに失敗してしまいます。

ちなみに以下がCloudTrailに記録されるイベント例。

CloudTrailに記録されるイベント例(展開してください)
CloudTrailに記録されるイベント例
{
  "eventVersion": "1.08",
  "userIdentity": {
      "type": "IAMUser",
      "principalId": "XXXXXXXXXXXXXXXXXXXXX",
      "arn": "arn:aws:iam::123456789012:user/testuser",
      "accountId": "123456789012",
      "accessKeyId": "YYYYYYYYYYYYYYYYYYYY",
      "userName": "testuser",
      "sessionContext": {
          "sessionIssuer": {},
          "webIdFederationData": {},
          "attributes": {
              "creationDate": "2022-11-20T03:11:57Z",
              "mfaAuthenticated": "true"
          }
      }
  },
  "eventTime": "2022-11-20T11:27:02Z",
  "eventSource": "codedeploy.amazonaws.com",
  "eventName": "StopDeployment",
  "awsRegion": "ap-northeast-1",
  "sourceIPAddress": "AWS Internal",
  "userAgent": "AWS Internal",
  "requestParameters": {
      "deploymentId": "d-3LVK9RJSK",
      "autoRollbackEnabled": true
  },
  "responseElements": {
      "status": "Succeeded",
      "statusMessage": "No more commands will be scheduled for execution in the deployment instances"
  },
  "requestID": "2ed04e08-daee-4ace-b132-f61e802f6cd0",
  "eventID": "69c587a6-eb5c-4fa3-a7cb-b9e735f81ba1",
  "readOnly": false,
  "eventType": "AwsApiCall",
  "managementEvent": true,
  "recipientAccountId": "123456789012",
  "eventCategory": "Management",
  "sessionCredentialFromConsole": "true"
}

また、後述する方法で取得したイベントオブジェクト例。

イベント発生時に実行されるイベントオブジェクト例(展開してください)
イベント発生時に実行されるAPI例
{
    "version": "0",
    "id": "fbc9cc14-052e-06c5-0b96-51965c1ca766",
    "detail-type": "AWS API Call via CloudTrail",
    "source": "aws.codedeploy",
    "account": "123456789012",
    "time": "2022-11-20T11:27:02Z",
    "region": "ap-northeast-1",
    "resources": [],
    "detail": {
        "eventVersion": "1.08",
        "userIdentity": {
            "type": "IAMUser",
            "principalId": "XXXXXXXXXXXXXXXXXXXXX",
            "arn": "arn:aws:iam::123456789012:user/testuser",
            "accountId": "123456789012",
            "accessKeyId": "YYYYYYYYYYYYYYYYYYYY",
            "userName": "testuser",
            "sessionContext": {
                "sessionIssuer": {},
                "webIdFederationData": {},
                "attributes": {
                    "creationDate": "2022-11-20T03:11:57Z",
                    "mfaAuthenticated": "true"
                }
            }
        },
        "eventTime": "2022-11-20T11:27:02Z",
        "eventSource": "codedeploy.amazonaws.com",
        "eventName": "StopDeployment",
        "awsRegion": "ap-northeast-1",
        "sourceIPAddress": "AWS Internal",
        "userAgent": "AWS Internal",
        "requestParameters": {
            "deploymentId": "d-3LVK9RJSK",
            "autoRollbackEnabled": true
        },
        "responseElements": {
            "status": "Succeeded",
            "statusMessage": "No more commands will be scheduled for execution in the deployment instances"
        },
        "requestID": "2ed04e08-daee-4ace-b132-f61e802f6cd0",
        "eventID": "69c587a6-eb5c-4fa3-a7cb-b9e735f81ba1",
        "readOnly": false,
        "eventType": "AwsApiCall",
        "managementEvent": true,
        "recipientAccountId": "123456789012",
        "eventCategory": "Management",
        "sessionCredentialFromConsole": "true"
    }
}

上記2つのJSONを比較したもの。
左がCloudTrailで記録されたJSON、右がイベント発生時に実行されるイベントオブジェクトのJSONです。

Monosnap_20221120_204407.png

イベント発生時に実行されるAPI

CloudTrailで記録されたイベントのJSONと、イベント発生時に実行されるAPIのJSONを比較すると、イベント発生時に実行されるイベントオブジェクトは以下のようにdetailの箇所に、CloudTrailに記録されるイベントが含まれることがわかるかと思います。

{
    "version": "0",
    "id": "fbc9cc14-052e-06c5-0b96-51965c1ca766",
    "detail-type": "AWS API Call via CloudTrail",
    "source": "aws.codedeploy",
    "account": "123456789012",
    "time": "2022-11-20T11:27:02Z",
    "region": "ap-northeast-1",
    "resources": [],
    "detail": {
      "CloudTrail のイベント記録"
    }
}

サンドボックスで試すだけならdetailより上に記載されている箇所を自分で適当に作って書式を合わせてもできるかと思いますが、それはそれで手間なので、イベント発生時に実行されるイベントオブジェクトを記録する仕組みを仕込んだ上で一度デプロイ停止のテストを行い、確認してみようと思います。

【参考】

イベントオブジェクトの出力

Lambdaのデベロッパーガイドにイベントオブジェクトの内容をログに記録するコードが書かれていたため、こちらを使っていこうと思います。

index.js
exports.handler =  async function(event, context) {
  console.log("EVENT: \n" + JSON.stringify(event, null, 2))
  return context.logStreamName
}

Lambda関数の作成

AWS Lambdaのダッシュボードより「関数の作成」から、以下のように設定して「関数の作成」を選択します。

Monosnap_20221120_212117.png

EventBridgeルールの作成

Amazon EventBridgeのダッシュボードより「ルール」→「ルールを作成」から以下のように設定して次へ進みます。

Monosnap_20221120_213150.png

そのまま下に進み、「イベントパターン」 の設定を以下の様に設定して次へ進みます。

今回の場合、CloudTrailに記録された情報を見ると、「AWSのサービス」、「イベントタイプ」は以下のような設定となるため、選択後、次へ進みます。

Monosnap_20221120_213316.png

ターゲットは先程作成したLambdaを指定して次へ進みます。

Monosnap_20221120_213425.png

そのまま次へ進み、「ルールの作成」ができたら完了です。

イベントオブジェクトの出力

EventBridgeのイベントが作成終わったら、実際にイベントを発生させてイベントオブジェクトを出力させます。

私の場合は、ブルーグリーンデプロイを停止したタイミングで出力されるため事象を発生させてみます。

今回Lambdaでイベント発生時のイベントオブジェクトを記録するようにしているので、ログはCloudWatch Logsに出力され、output_event_objectと言った名前で設定した場合は「/aws/lambda/output_event_object」といったロググループに出力されております。

ログストリームにdetail等の項目を含んだJSON形式のログが出力されていれば成功です。

Monosnap_20221123_092131.png

サンドボックスへのログ貼り付け

EventBridgeに戻り、「サンドボックス」→「イベントパターン」を選択し、以下のようにして先程CloudWatch Logsに出力されたログをサンプルイベントにコピペします。
※1行目のCloudWatch Logsのログメッセージは不要

項目 設定
イベントソース AWSイベントまたはEventBridgeパートナーイベント
サンプルイベント ご自身名前を入力
入力欄 CloudWatch Logsに出力されたログのコピペ

Monosnap_20221121_093600.png

イベントパターンの作成

いよいよイベントに合致させるイベントパターンを作成し、書式があっているかを確認してみようと思います。

イベントパターンは自分で最初から作成することもできますが、それだと大変なので、以下のようにメニューから選択して雛形を作ってから必要な部分を自分で追加してみます。

今回は「特定のオペレーション」に、デプロイを停止した際のオペレーションとなる「StopDeployment」を指定して、デプロイ停止時のアクションをトリガーとするイベントパターンを作成してみます。

Monosnap_20221121_221931.png

入力し終わって「テストパターン」ボタンを押すとサンプルイベントとイベントパターンのチェックが行われ、イベントパターンに一致すれば以下のように表示されます。

イベントパターンに一致したサンプルイベント

イベントパターンの内容が一致しなければ以下のように表示されます。

サンプルイベントがイベントパターンと一致しませんでした

そもそもサンプルイベントの書式が誤っていたりする場合は以下のように表示されます。

サンプルイベントは無効です。

最初、CloudTrailのログそのままコピペすれば良いものだと思って試していた際は、JSONのフォーマットチェックは通るのにイベントパターンに何を書いても失敗していたので、ここに何を書けば通るのかわからずだいぶ悩みました。

イベントパターンの編集

上記ではeventNameStopDeploymentに指定してチェックしましたが、「パターンを編集」を選択することで、以下のように直接編集できる画面に切り替わります。

イベントパターンに記載される内容はCloudWatch Logsに出力されたJSON形式のログのうち、マッチさせたい内容を記載すればOKです。

但し、CloudWatch Logsのログをそのままイベントパターンに記載するのではなく、階層構造はそのままで、Value(値の部分)は[]でくくる必要があります。

以下はautoRollbackEnabledstatusの値もパターンマッチの条件にした場合の例。

Monosnap_20221121_222949.png

おわりに

いちいち事象を発生させてトライアンドエラーで進めていかなくても、一度イベントログを出力してからサンドボックスで確認すれば、イベントパターンがマッチするかを試せるのは非常にやりやすいと感じました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0