[AWS] EventBus で別アカウントにイベントを送信する／受信する

メモ代わりの殴り書きです。
あとで書き直すかもしれないし、書き直さないかもしれない。


# EventBus の概要
EventBus は、他のアカウントやリージョンにイベントを連動できる機能。
以前は CloudWatch Events の一部であったが、今は EventBridge というサービスに統合されている。
CloudWatch Events の EventBus が無くなったわけでは無い。
リソース実物は同じなのにインタフェースが違うという、少しややこしい状況。
EventBridge のほうができることが多い。

この記事では EventBridge のほうから使う前提で。

# 設定

## 必要なリソース

* [受信側]
  * EventBus
     * EventBus Policy
* [送信側]
  * EventRule
      * Target
         * IAM Role

## 各リソースの動作・設定の要約
* これは最低限。受信側にTargetがないので、イベントを受け取るだけで何もしない。
   動作確認したいなら SNS Topic や Lambda に繋げるよろし。
* EventBus でイベントを受け取る。
* 受信側のイベントバスには、送信側からの `events:PutEvents` を受け入れるリソースポリシーが必要。
* 送信側は、受信側イベントバスを宛先としたターゲットを設定する。
    * そのターゲット設定には、 `Action: "events:PutEvents"` と `Resource: "受信側EventBusのARN"` の権限を持つ Role が必要。

### 補足
* 送信側の EventTarget を作成するとき、送信先（受信側）の EventBus が存在していなくても登録できる。
* 送信側は AWS CLI/SDK で put_evnets が実行できそう。
  なので、厳密にいえば送信側にはリソースは何もいらないのかもしれない。権限さえれば。
  検証はしていないので間違ってるかも。

## 設定詳細（大事なところだけ抜粋）

### 受信側イベントバスのポリシー
```json
{
    "Version" : "2012-10-17",
    "Statement" : [{
      "Sid" : "allow_account_to_put_events",
      "Effect" : "Allow",
      "Principal" : {
        "AWS" : "arn:aws:iam::<送信元アカウントID>:root"
      },
      "Action" : "events:PutEvents",
      "Resource" : "<受信側EventBusのARN>"
    }]
}
```

### 送信側イベントルールのイベントパターン例
飛ばしたいイベントのパターンを書く。
送信側のイベント検知の設定であるので、特別なことは何もない。通常のイベントパターン通り。
下記イベントパターンは、指定されたS3オブジェクトがPutされたときに発火する。
※CloudTrailのデータイベント設定で当該S3を監視する設定が必要。

```json
{
  "detail": {
    "eventName": ["PutObject", "CompleteMultipartUpload", "CopyObject"],
    "eventSource": ["s3.amazonaws.com"],
    "requestParameters": {
      "bucketName": ["<S3-BucketName>"],
      "key": ["<S3-Key>"]
    }
  },
  "detail-type": ["AWS API Call via CloudTrail"],
  "source": ["aws.s3"]
}
```

### 送信側ターゲット用ロールのポリシー
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "events:PutEvents",
            "Resource": "<受信側EventBusのARN>"
        }
    ]
}
```

### 受信側イベントルールのイベントパターン例
上記のリソースでは受信側にルール・ターゲットを設定していないが、設定するとしたらこうなる。

イベントバスで受け取ったイベントであるが、こちらも特別な書き方は不要。
通常のイベントパターンと同様の記述内容になる。
ただし、アカウントは制限しておいたほうがよい。（後述）

```diff_json
{
  "detail": {
    "eventName": ["PutObject", "CompleteMultipartUpload", "CopyObject"],
    "eventSource": ["s3.amazonaws.com"],
    "requestParameters": {
      "bucketName": ["<S3-BucketName>"],
      "key": ["<S3-Key>"]
    }
  },
  "detail-type": ["AWS API Call via CloudTrail"],
  "source": ["aws.s3"],
+  "account" : ["<送信元アカウントID>"]
}
```

## 必須ではないが考慮しておくべきこと。
* 受信側のトリガー（イベントパターン）は、アカウントやサービス・アクションを絞っておくべき。特にアカウント。  
  全く想定していないアカウントのイベントを送り付けられると非常に困る。
* 送信側も適切に絞っておかないと、CloudTrail荒らしになる。


# 補足事項：イベント情報の構成
マネコンからイベントルールを書くと、いくつか選択肢があって選んでいくとある程度は自動的にイベントパターンを設定してくれるが、細かい条件を追加しようと思うとどう書いたらよいのかが分からない。分かりづらい。
なので、イベント情報の構成を知っておきたい。

Events がキャッチするイベントは下記jsonの構成になっている。例外はあるかもしれないが未確認。
CloudTrail のイベント情報をラッピングする形。
イベントパターンを書くときは、この構成に合わせて各要素のマッチ条件を書いていく。

```json
{
    "version": "0",
    "id": "********-****-****-****-*************",
    "detail-type": "AWS API Call via CloudTrail",
    "source": "aws.s3",
    "account": "***********",
    "time": "2022-02-01T04:31:54Z",
    "region": "ap-northeast-1",
    "resources": [],
    "detail": {
        "eventVersion": "1.08",
        "userIdentity": {
            ...
            ...
        },
        ...
        <CloudTrailのイベントレコードと同一>
    }
}

```