【AWS】CloudWatch Event Bus（イベントバス） 機能でクロスアカウント間イベント転送

#はじめに
業務上に、異なるAWSアカウント間でのアラーム統一管理ニーズがありました。
調べたところ、CloudWatchのEvent Bus機能が使えそうなので、それを使ってクロスアカウント間でCloudWatchイベント転送を実現してみました。

#構成図
今回の構成図は下記となります。
![CloudWatch Event Bus構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/94aea433-e10c-19e6-8340-9cbdd5e6d03a.png)
今回はアカウントAのEC2が停止したら、CloudWatchのEvent Bus機能を経由し、アカウントBのSNSでメールを送信させるという仕組みになります。
なお、今回はアカウントAでEC2をCloudWatchのターゲットにしていましたが、それとほかに、Lambda、API Gatewayのサービスも使えます。いろいろと用途が幅広く、AWSクロスアカウント間でCloudWatchを経由して何かの機能を実現したときに、ぜひご参考ください。

#１．アカウントBで、アカウントAとのイベントバス追加
アカウントBのAWSマネジメントコンソール画面に、「CloudWatch」を入力し、クリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/6048cacb-e679-3ee2-c2fd-807f8fe89ebc.png)
***

左側メニューに「イベントバス」をクリックし、次に「アクセス許可の追加」をクリックします。
![1111.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/afca57af-bf33-c61c-6149-c2124c671b1b.png)
***

アカウントID欄に、アカウントAのIDを入力し、「追加」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/06e81204-6bc7-1b26-b09e-0b0493cdae6e.png)


#２．アカウントBでSNSトピックを作成
アカウントBのAWSコンソール画面からSNSを検索し、下記のようにSNS機能画面にアクセスします。
左側メニューから「トピック」をクリックし、「トピックの作成」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/cb0d1d1c-ba80-a852-cc90-71cf7ff956c5.png)
***

名前欄に命名規則に従って名称を入力し、ほかの設定はそのままデフォルトにして作成します。今回はテストのため、テスト名を入れました。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/ae923771-32b4-1a99-2cfb-9c9570acaea6.png)
***

上記作成したトピックに入り、「サブスクリプションの作成」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/ce1fe062-ed2e-f247-42a7-3190a7089f6a.png)
***

トピックARNを上記作成したトピックのARNを選びます。
プロトコル欄に「Eメール」をクリックします。
エンドポイントに受信したいメールアドレスを入力します。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/34660055-9928-3068-4cfe-18a433d02d5b.png)
***

これでサブスクリプションが作成しました。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/9e039e5c-11d0-2890-e0cd-655e24eee4e7.png)
***

上記ご入力したメールに、AWSからのメッセージが届きます。
「Confirm subscription」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/c8d9cb98-be61-4e19-c417-a4d459154a75.png)
***

下記のように「Subscription confirmed!」というメッセージが表示されれば成功です。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/95cb86d5-7175-ba94-1814-1a988f315ad1.png)

#３．アカウントAでCloudWatchのルール作成
アカウントAでCloudWatch画面に入り、左側メニュー「ルール」をクリックし、「ルールの作成」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/cf2ac9e2-2e19-5de9-fb41-7105f36ae03c.png)
***

「イベントパターン」をクリックします。
サービス名に「EC2」を選択します。
イベントタイプに「EC2 Instance State-change Notification」を選択します。
→「特定の状態」をクリックし、「Stopped」を選択します。
→「特定のインスタンスID」をクリックし、通知したいインスタンスのIDを入力します。
ターゲットに「別のAWSアカウントのイベントバス」を選択し、アカウントBのIDを入力します。
下記「この特定のリソースに対して新しいロールを作成する」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/c0341430-d225-ccd5-456e-f451c0bb1db0.png)
***

次に「設定の詳細」をクリックし、名称を入れます。（※ここで省きます）
下記のように、ルールの作成が完了しました。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/9cbefe3f-e2db-3e74-de4f-aa7f23865046.png)

#４．アカウントBでCloudWatchのルール作成
アカウントBでCloudWatch画面に入り、左側メニュー「ルール」をクリックし、「ルールの作成」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/dcd16cec-9acd-bec7-cec4-8033f800683b.png)
***

イベントパターンをクリックし、下記のJSONコードを入力します。

```code
{
  "source": [
    "aws.ec2"
  ],
  "account": [
    "アカウントAのID"
  ],
  "detail-type": [
    "EC2 Instance State-change Notification"
  ],
  "detail": {
    "state": [
      "stopped"
    ]
  }
}
```
ターゲット欄に「SNSトピック」を選択します。
トピックは上記手順２で作成したトピックをお選びください。
[Input Path] に以下を入力します。

```code2
{"instance-id":"$.detail.instance-id", "state":"$.detail.state", "time":"$.time", "region":"$.region", "account":"$.account"}
```

[Input Template] に以下を入力します。

```code
"At <time>, the status of your EC2 instance <instance-id> on account <account> in the AWS Region <region> has changed to <state>."
```

※カスタマイズした内容を入力することもできます。
「詳細の設定」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/fa75126f-fa1f-3082-6151-a587622aa3fd.png)
***

名前欄に命名規則に従って名称を入れます。
「ルールの作成」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/2d7b8f5d-2c9d-889d-fc05-e2b9a2089b9b.png)
***

#５．テスト
上記３で指定したインスタンスを停止してみます。
該当インスタンスを右クリックし、「インスタンスの状態」→「停止」をクリックします。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/c847d5fd-7561-3b60-b04a-3b53e2624e32.png)
***

下記のように、インスタンス停止のお知らせがメールに届いております。	
これでクロスアカウント間CloudWatchによるEC2ステータス変化メール通知機能が実現できました。
![1112.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/865613/cc67f485-c727-e82c-2737-bbeeefd6ac95.png)

#最後
CloudWatchのEvent Bus機能はいろいろとクロスアカウント間で幅広く使えるので、今回はEC2停止だけを試しました。AWSクロスアカウント間でCloudWatchを経由して何かの機能を実現したときに、ぜひご参考ください。

#参考資料
１．https://dev.classmethod.jp/articles/cloudwatch-events-event-bus/
２．https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/CloudWatchEvents-CrossAccountEventDelivery.html
３．https://docs.aws.amazon.com/AmazonCloudWatch/latest/events/CloudWatchEvents-CrossAccountEventDelivery.html