HeatlhEventの通知を一つのアカウントへ集約する

## 概要

- 複数のAWSアカウントで発生したHealthイベントを一つのアカウントで確認できるようにしたい
- 上記要件を実現するために、EventBridgeのクロスアカウント送受信を使用する
- **AWS Organizationを使用して複数アカウントを管理できる場合はもっと簡単に集約する方法がある**が、諸事情によりメンバーアカウントの中だけで集約する必要があったため、今回の対応を実施

## 構成
![healthevent.drawio (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/3e520dee-2cfd-b407-f3fe-768d83dc8fea.png)

- 集約するイベントを受信するアカウントをアカウントA、イベントを送信するアカウントをアカウントBとする
- 各アカウントでイベントを補足したいリージョンすべてにEventBridgeルールを設定する
  - 今回は東京リージョンとバージニア北部リージョンで構成
- イベントをユーザに通知する手段として**User Notificaions**を採択。Amazon SNSを使うことも可能だが、可読性の高いHTMLメールで送信されるため、こちらを選択した

## 設定手順

### アカウントA

アカウントAのイベントバスへ配信されたイベントを処理するための設定を行う

#### User Notificaionsの設定

##### 通知チャネルの作成

- User Notificationsの画面から「配信チャネル」→「Eメールの追加」をクリック
- 「受信者」に通史を送信するメールアドレス、「名前」に対象を識別するための名前を入力
- 「Eメールの追加」をクリック
- 検証用のメールが送信されるので、メール本文内の「Verify Email」をクリックして検証を済ませる

##### 通知設定の作成
![スクリーンショット 2024-10-21 145058.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/f0c217c4-989e-3272-d406-2b99d32ee935.png)

- 画面右上「QuickSetup」にて「Health」を選択
- 「通知設定を作成」をクリック
- 「リージョン」に「US East(N. Virginia)」と「Asia Pasific(Tokyo)」を選択する
- 「Eメール（オプション）」に前工程で作成した通知チャネルを設定する
- 「通知設定を作成する」をクリック

通知設定を作成することで、自動でHealthイベントを処理するためのEventBrigdeルールが各リージョンに作成される。今回の場合は、東京リージョンとバージニア北部リージョンの計2つ作成される。

#### イベントバスの設定

- EventBridgeの「イベントバス」から「default」をクリック
- 「許可」タブから「アクセス許可」をクリック
- 「リソースベースのポリシー」のテキストボックスへ以下のポリシーを設定する（バージニア北部の場合）

  ```json
  {
    "Version": "2012-10-17",
    "Statement": [{
      "Sid": "AllowPutEventsFromSpecificAccount",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<アカウントBのID>:root"
      },
      "Action": "events:PutEvents",
      "Resource": "arn:aws:events:us-east-1:<アカウントAのID>:event-bus/default"
    }]
  }
  ```

- 「更新」をクリックする

### アカウントB

アカウントBのイベントバスへ配信されたイベントをアカウントAのイベントバスへ転送するための設定を行う

#### IAMロールの作成

アカウントAへイベントを配信するための権限を付与するためのIAMロールを作成する。手順は割愛するが、使用したポリシードキュメントは以下の通り。

信頼関係ポリシー

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "events.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

IAMポリシー

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "events:PutEvents",
      "Resource": "arn:aws:events:*:<アカウントAのID>:event-bus/default"
    }
  ]
}
```

#### EventBridgeルールの作成

##### 東京リージョン

- EventBridgeの画面から「ルールを作成」をクリック
- ステップ１：任意の名前を入力して、「次へ」をクリック
- ステップ２：「イベントパターン」へ以下のパターンを設定して「次へ」をクリック

  ```json
  {
    "source": ["aws.health"],
    "detail-type": ["AWS Health Event"]
  }
  ```

- ステップ３：「ターゲット1」へ以下のパラメータを入力する
  - ターゲットタイプ：EventBrigdeイベントバス、「別のアカウントまたはリージョンのイベントバス」
  - ターゲットとしてのイベントバス：アカウントAの東京リージョンのイベントバスのARN
  - 実行ロール：前工程で作成したIAMロールを指定
- ステップ４：タグを設定
- ステップ５：「ルールの作成」をクリック

##### バージニア北部リージョン

東京リージョンと同様の手順でルールを作成する

:::note info
同じリソースを繰り返し作成する形になるので、工数・作業ミスの観点からこの辺はTerraformなどで作成したほうがベターです
:::

### 動作確認

ここまでAWSのHealthイベントを扱うためのリソースを作成・設定してきましたが、実は動作確認のためにテスト用のHealthイベントを意図的に発生させることができません。従って、今回は一緒にGuardDutyのFindingsを検出した時のイベントルールを追加し、こちらが正しく集約できるかを確認します。

#### アカウントAの追加設定

User NotificaionsにGuardDuty Findingsの設定を追加します。以下のEventBrigdeルールが生成されていればOKです。

```json
{
  "source": ["aws.guardduty"],
  "detail-type": ["GuardDuty Finding"]
}
```

#### アカウントBの追加設定

Healthイベントの設定と同様の手順で、GuardDutyの設定を追加します。アカウントAと同様のGuardDuty用のイベントパターンを設定したルールを作成します。

#### アカウントAの動作確認

アカウントAのCloudShellを起動し、以下のコマンドを実行します。実行後、EventBridgeがイベントを検出するまで、5～10分ほど掛かるのでしばらく待ちます。

実行するコマンド例：

```bash
aws guardduty create-sample-findings \
--detector-id $(aws guardduty list-detectors --query 'DetectorIds' --output text) \
--finding-types Policy:S3/AccountBlockPublicAccessDisabled --region <対象リージョン>
```

##### 東京リージョンイベント
![A_ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/cfaa43ca-0f74-f8ae-ad96-14f2760029d9.png)


##### バージニア北部リージョンイベント
![A_us-east-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/3582a798-d4c8-bce4-7236-a503617fe2ed.png)

#### アカウントBの動作確認
同様にCloudshellから、サンプルイベントを発行して動作確認を行います。

##### 東京リージョンイベント
![B_ap-northeast-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/cd22768f-4137-af7b-9c26-2dcd89bcbb0c.png)

##### バージニア北部リージョンイベント
![B_us-east-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389171/aed924ff-a6b5-ded3-237d-939b9f5ec3b1.png)

アカウントAの通知チャネルに設定したメールアドレスで、アカウントA/Bのイベントに関するメールを受信できることを確認できました。

## 注意点
クロスアカウントでイベント送受信をする際、別リージョンのイベントを転送した場合、User Notificaionsでは処理できないので注意。（アカウントBのバージニア北部リージョンのイベントをアカウントAの東京リージョンのイベントバスへ転送しても、User Notificaionsで処理されない）

## 参考ドキュメント

- [Sending and receiving events between AWS accounts in Amazon EventBridge](https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-cross-account.html)