EventBridgeを使用してクロスアカウント間でGlueジョブを連携してみた

# 背景・目的
別アカウントで作成したデータを元に、Glueジョブで処理するケースがあります。
このような場合に、Glue Trigger等のスケジューラーで特定の時間になったら起動し動き出すこともできますが、入力データの作成が遅れた場合などに空振りするケースがあります。
そこで、別アカウントで準備ができたら、Glueジョブを起動してもらう方法が考えられます。
本ページでは、この仕組みを試してみたいと思います。

# まとめ
- クロスアカウント間でシームレスにGlueジョブを動かしたい場合に使用できます。
- ソース側のGlueのステータスを検知するEventBridgeのバスは、Defaultでしか拾えないので注意が必要です。
- EventBridgeからGlueを起動する場合、GlueジョブではなくGlueWorkflowを指定する必要があります。


# 概要
今回は、下記のような構成を試してみたいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f771f7f1-3c07-c276-fe6d-11ef047b886a.png)

- アカウントAとアカウントBを用意する。
- アカウントAとアカウントB間でEventBridgeを介してメッセージを送受信する
- アカウントAではS3出力後に、EventBridgeにメッセージ送信します。
- アカウントBではEventBrdigeからGlueジョブを起動します。

# 実践
## 事前準備
### S3バケットの用意（アカウントA、アカウントB）
それぞれのアカウントでS3バケット（Send BucketとTarget Bucket）を用意します。

#### 送信側のアカウントAのS3バケットポリシーを設定
1. アカウントBのGlueロールからアクセス可能なようにバケットポリシーを設定します。
    ```
    {
        "Version": "2012-10-17",
        "Id": "Policy1679145460562",
        "Statement": [
            {
                "Sid": "Stmt1679145458128",
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::XXXXXXX:role/XXXXXXXX"
                },
                "Action": [
                    "s3:GetObject",
                    "s3:GetObjectAcl",
                    "s3:ListBucket"
                ],
                "Resource": [
                    "arn:aws:s3:::XXXXXXX",
                    "arn:aws:s3:::XXXXXXX/*"
                ]
            }
        ]
    }
    ```

## Glueの作成
### 送信側のアカウントA
#### Glueジョブを作成
1. 下記のようにシンプルにインプットとアウトプットのS3バケットをつなぐジョブを作成します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/38a22bb5-9e3c-1657-0565-83d3f11eeaea.png)


### 受信側のアカウントB
#### Glueジョブを作成
1. 下記のようにシンプルにインプットとアウトプットのS3バケットをつなぐジョブを作成します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/ed889f9d-741e-4896-f5d5-d14033c8999f.png)

#### Glueワークフローを作成
EventBridgeから起動できるように、Glueワークフローを作成します。

1. Glueのナビゲーションペインでワークフローをクリックし、「ワークフローの追加」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/070eb060-8870-e262-9af0-207c45eb9f95.png)

1. 下記を入力し、「ワークフローの追加」をクリックします。
    - ワークフロー名
    - 最大同時実行数
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/73a274c5-61e3-3dea-7f98-7f22d61c1ef2.png)

1. ワークフローにトリガーとジョブを追加します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/e3674348-57a6-4d9a-163f-dd58d21e19d6.png)


## Event Brdigeの設定
### 受信側のアカウントB
#### カスタムイベントバスを作成
1. カスタムイベントバスを「eventbridge-bus-glue-notice」という名前で作成します。リソースポリシーは下記のとおりです。
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/9d47b46b-a306-2b05-b90c-8db628bade95.png)
    ```
    {
      "Version": "2012-10-17",
      "Statement": [{
        "Sid": "eventbridge-bus-glue-notice",
        "Effect": "Allow",
        "Principal": {
          "AWS": "arn:aws:iam::{Account-A}:root"
        },
        "Action": "events:PutEvents",
        "Resource": "arn:aws:events:ap-northeast-1:{Account-B}:event-bus/eventbridge-bus-glue-notice"
      }]
    }
    ```

#### Eventルールを作成
次にEventルールを作成します。
1. イベントルールの画面で、作成したカスタムイベントバスを選択した状態で「ルールを作成」をクリックします。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/9c6ab806-3e79-f784-4348-f45835f605c1.png)

1. 下記を選択し「次へ」をクリックします。
    - ルール名：任意
    - イベントバス：作成したイベントバスを指定
    - ルールタイプ：イベントパターンを持つルール
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f80fa2c6-058a-e5b4-11f4-dec93eb25317.png)

1. 下記を入力し、「次へ」をクリックします。
    - イベントソース：AWSイベントまたはEventBridgeパートナーイベント
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/8e97a395-1fc4-1322-fa09-ccb95a971366.png)

    - イベントパターン
        ```
        {
          "source": ["aws.glue"],
          "detail-type": ["Glue Job State Change"],
          "detail": {
            "jobName":["eventbus-test-source-job"]
            ,"state": ["SUCCEEDED"]
          }
        }
        ```
1. 作成したGlueWorkflowを指定してターゲットを選択します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/700a9ed4-356a-0efe-6642-fb6c76e36bcc.png)

1. タグの選択、確認後ルールを作成します。

### 送信側のアカウントA
#### Eventルールを作成
次にEventルールを作成します。
1. イベントルールの画面で、Defaultを選択した状態で「ルールを作成」をクリックします。
1. 下記を選択し「次へ」をクリックします。
    - ルール名：任意
    - イベントバス：作成したイベントバスを指定
    - ルールタイプ：イベントパターンを持つルール
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6408e3c3-6dc1-8e0e-4626-f5d0076ba1bd.png)

1. 下記を入力し「次へ」をクリックします。
    - イベントソース：イベントソース：AWSイベントまたはEventBridgeパートナーイベント
        ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/06e69474-4806-8571-7a36-16d50472a1e5.png)
    - イベントパターン
        ```
        {
          "source": ["aws.glue"],
          "detail-type": ["Glue Job State Change"],
          "detail": {
            "jobName":["eventbus-test-source-job"]
            ,"state": ["SUCCEEDED"]
          }
        }
        ```
1. 「ターゲットを選択」画面で、下記を入力し「次へ」をクリックします。
    - ターゲットタイプ：
        - EventBridge イベントバス
        - 別のアカウントまたはリージョンのイベントバス
    - ターゲットとしてのイベントバスに送信先のイベントバスARN
    - 実行ロール：この特定のリソースについて新しいロールを作成
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fbc30a59-12ec-7a3e-67d3-b56daa1849a0.png)

1. タグの選択、確認後ルールを作成します。

## 検証
### 実行前の確認
1. 送信側（アカウントA）のSourceバケットを確認します。JSONファイルがあります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/13f03b39-435a-8562-936a-aec38cf06e40.png)

1. 送信側（アカウントA）のSendバケットを確認します。データはありません。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/52a97963-1e16-b128-bc51-83e4e3cc0912.png)

1. 受信側（アカウントB）のTargetバケットを確認します。データはありません。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/834bb320-0cfb-db8d-9e51-7f6460ba6c38.png)

### 実行
1. 送信側（アカウントA）のGlueジョブを実行します。（すぐに終わりました。）
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c60ea070-bf68-402a-b7ee-5a2c775f6933.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/8be1015a-c3cd-c948-2133-0f9f7de8edc7.png)

### 実行後の確認
1. 送信側（アカウントA）のSendバケットを確認します。データが作成されています。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/c823aece-bae3-6bdf-e108-2c79fa9ef5ae.png)

1. 受信側（アカウントB）のワークフロー履歴を確認します。完了しました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/b5cbc204-8089-70c7-1b44-ff3694369b30.png)

1. 受信側（アカウントB）のジョブを確認します。問題なく終了しています。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/bdb17843-70ef-3b60-dcbd-18cf63c96bde.png)

1. 受信側（アカウントB）のTargetバケットを確認します。データが作成されています。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6c23c263-de4c-281b-3941-bf90aab3d1b5.png)

# 考察
- S3のPutObject等のイベントをトリガーにジョブを実行することも可能ですが、ある程度、まとめてバッチ処理を行いたい場合に、シームレスにジョブを動かしたい際に有効と感じました。


# 参照
https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-cross-account.html