Organizations連携で集約したAWS Personal Health Dashboardのイベントを通知するAWS Health Aware (AHA)を試してみた

Organizationsで集約したPHDのイベントを通知してくれるソリューションがあったよ。
2021.10.13

去年アップデートでOrganizations連携にPersonal Health Dashboard(PHD)が追加され、コンソール上からは組織内のイベントを集約して確認できるようになりました。

そこで集約したイベントをCloudWatch Eventsで拾い、通知させる仕組みを実装しようとしたんですが、公式ドキュメントに以下の記載があるのを見つけてしまいました。

You can create a CloudWatch Events rule to receive notifications for only your account. You can't receive organizational events for other accounts in your AWS Organizations.

翻訳:CloudWatch Eventsのルールを作成して、自分のアカウントだけの通知を受け取ることができます。AWS Organizationsの他のアカウントの組織イベントを受け取ることはできません。

参考:Monitoring AWS Health events with Amazon CloudWatch Events - AWS Health

どうやらOrganizations連携で集約したイベントはマネジメントアカウント上からは拾うことができないようです。なんでや…

というわけで、なんかいい方法ないかな〜と調べていたところ、丁度いいソリューションがAWSから提供されているのを発見。早速試してみることにしました。

概要

AWS Health Aware (AHA)とはAWSが提供しているソリューションです。CloudFormationを展開することで、Organizations連携で集約したPHDのアラートを通知する仕組みを簡単に実装できます。(今回はOrganizations環境での利用を想定していますが、そうでない場合も利用できます。)通知先としてはSlack、Microsoft Teams、Amazon Chime、Eメールアラートがデフォルトで用意されており、EventBridgeを利用することでその他の通知先にも連携が可能です。

アラートの内容にはコンソールで確認できる障害時に影響を受けるAWSアカウントとリソース情報等も含まれています。

引用:AWS Health Aware – Customize AWS Health Alerts for Organizational and Personal AWS Accounts | AWS Management & Governance Blog

通知されるイベント

PHDのイベントログに表示されるものが対象となります。そのためパブリックイベント、アカウント固有のイベント両方が通知されることになります。イベントログの詳細についてはこちらをご参照ください。

イベントカテゴリでも分けることができ、全て通知させるかissueに振り分けられたものだけを通知させるかを選択することも可能です。

アーキテクチャ

アーキテクチャは以下の通りです。

引用:AWS Health Aware – Customize AWS Health Alerts for Organizational and Personal AWS Accounts | AWS Management & Governance Blog

リソース 説明
DynamoDBTable イベントARN、アップデート、TTLを保存するために使用されるDynamoDBテーブル
ChimeChannelSecret AWS SecretsManagerに保存されているAmazonChimeのWebhookURL
EventBusNameSecret AWS SecretsManagerに保存されているAmazonEventBridgeのEventBusARN
LambdaExecutionRole LambdaFunctionに使用されるIAMロール
LambdaFunction AWS Health APIから読み取り、エンドポイントに送信し、DynamoDBに書き込むメインのLambda関数
LambdaSchedule LambdaFunctionを呼び出すために毎分実行されるAmazonEventBridgeルール
LambdaSchedulePermission LambdaScheduleに使用されるIAMロール
MicrosoftChannelSecret AWS SecretsManagerに保存されているMicrosoftTeamsのWebhookURL
SlackChannelSecret AWS SecretsManagerに保存されているSlackのWebhookURL

1分に1度EventBridgeルールがLambdaを起動し、PHDに集約したイベントを取得しています。通知対象となるイベントがあった場合は、Lambdaから通知処理とDynamoDBへの通知情報の保存が行われます。Lambdaの中では取得したイベントを通知する前に、DynamoDBに登録されている情報をArnをキーに取得し、APIで取得した情報が新規もしくは更新されたものかをチェックしています。そのため、同じ通知が何度も行われることはありません。

この構成はシングルリージョンですが、マルチリージョンに展開することで可用性を高めることも可能です。マルチリージョンで展開する場合はDynamoDBテーブルをグローバルテーブルとして利用するようにCloudFormationのパラメータを設定します。その場合も同じよう通知が重複することはありません。

DynamoDBテーブルにはTTLが設定されており、更新が無くなってから24時間で項目が削除されます。

アーキテクチャとしてはサーバレス構成で、処理内容はLambdaで完結しています。そのため料金も非常に安価で利用できるようになっているので、いい感じに利用できそうですね。

やってみた

それでは実際にソリューションの展開と通知をやっていきます。

前提

  • HealthOrganizational Viewが有効になっていること
  • Gitが利用できること
  • 少なくとも1つは通知先情報が用意してあること
    • Slack・Microsoft Teams・Amazon Chime・Email・Amazon EventBridge
    • 個別の設定手順はこちらを参照
  • AWSアカウントの契約がAWSビジネスまたはエンタープライズサポートプランであること

SlackのWebhook URL取得(任意)

私は通知先としてSlackを使いたいのでWebhook URLを取得します。Slackを使う方は実施してください。Webhook URLの取得方法はこちらを参考にさせていただきました。

SlackのWebhook URL取得手順 - Qiita

事前準備

CloudFormationを実行するために事前準備していきます。

S3バケットの作成

CloudFormationを展開する前にLambdaのコードをアップロードするためのS3バケットを作成します。今回は東京リージョンにaha-{アカウントID}というバケットを作成しています。リージョンはAHAを展開したいリージョンと合わせてください。バケット名は任意のものでも問題ありません。

Gitからクローン

CloudFormationテンプレートやLambdaのコード等をGitからファイルを以下からクローンします。

ターミナルから任意の場所で以下のコマンドを実行してください。

$ git clone https://github.com/aws-samples/aws-health-aware.git

以下のようなフォルダが作成されることを確認してください。(更新によって多少違いがあるかもしれません。)

aws-health-aware
├── BETA-terraform
│   ├── README.md
│   ├── Terraform_DEPLOY_AHA
│   │   ├── Terraform_DEPLOY_AHA.tf
│   │   └── terraform.tfvars
│   └── Terraform_MGMT_ROLE
│       └── Terraform_MGMT_ROLE.tf
├── CFN_DEPLOY_AHA.yml
├── CFN_MGMT_ROLE.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── handler.py
├── messagegenerator.py
└── readme-images
    ├── aha-arch-multi-region.png
    ├── aha-arch-single-region.png
    ├── aha-logo.png
    ├── aha_banner.png
    ├── architecture.png
    └── workflow.png

コードのアップロード

Lambdaとして実行するhandler.pymessagegenerator.pyをS3にアップロードする必要があるので2つのファイルを1つのzipに圧縮します。任意のファイル名で良いのですが、今回は手順内でおすすめされていたaha-v1.8.zipとします。このzipファイルを先ほど作成したaha-{アカウントID}のバケットにアップロードしてください。

AHAの展開

事前準備ができたらAHAのソリューションを展開していきます。AWSコンソールへログインしてCloudFormationを開きます。

クローンしたフォルダの中からCFN_DEPLOY_AHA.ymlをCloudFormationのコンソールからアップロードして次へを押します。

スタックのパラメータ

スタックのパラメータを設定できる画面になるのですが、非常に多くのパラメータが設定できるので1つずつ確認していきます。スタック名はAHA-Deploymentで作成して、通利先にはSlackを利用します。

AWS Organizations Enabled?

HealthOrganizational Viewが有効になっているかどうかを選択します。有効になっている場合はYesを選択することで、PHDに集約されたイベントのアラートを受け取ることができます。Noの場合でもSHDのアラート通知を受け取ることができます。

今回はHealthOrganizational Viewを有効化しているのでYesを選択します。

The types of events to get alerted on

AHAで検知するイベントカテゴリを選択できます。今回は全てのイベントを対象とするので、issue | accountNotification | scheduledChangeを選択します。

Name of S3 Bucket

先ほどzipをアップロードするのに作成したバケット名を指定します。今回はaha-{アカウントID}を指定しています。

Name of .zip file in S3 Bucket

先ほどアップロードしたzipファイル名を指定します。今回はaha-v1.8.zipとして指定します。

Communication Channels - Slack/Microsoft Teams/Amazon Chime And/or EventBridge

利用する通知先を以下から1つ以上入力します。複数の通知先を設定しても大丈夫です。

  • Slack Webhook URL
  • Microsoft Teams Webhook URL
  • Amazon Chime Webhook URL
  • EventBusName

今回はSlackへ通知させるため、Webhook URLを入力します。

Email Setup - For Alerting via Email

差出人と宛先の電子メールアドレス、および電子メールの件名を入力します。利用しない場合はデフォルトのままにしておきます。

EventSearchBack

何時間前までさかのぼってイベントを検索するかを時間単位で指定します。デフォルトは1時間です。

Which regions to search for events in

どのリージョンに対するイベントを通知するのかを選ぶことができます。デフォルトでは全リージョンを対象になっています。特定のリージョンについてレポートしたい場合は、カンマ区切りで10個まで入力してください。SCPで特定のリージョンのみに使用を制限している環境を運用している場合は、利用外のリージョンの情報はノイズになるので絞るのがおすすめです。

利用可能なリージョン:us-east-1、us-east-2、us-west-1、us-west-2、af-south-1、ap-east-1、ap-south-1、ap-northeast-3、ap-northeast-2、ap-southeast-1、ap-southeast-2、ap-northeast-1、ca-center-1、eu-center-1、eu-west-1、eu-west-2、eu-south-1、eu-south-3、eu-north-1、me-south-1、sa-east-1、global

ARN of the AWS Organizations Management Account assume role (if using)

PHDイベントを収集するための管理アカウントのIAMロールのArnです。マネジメントアカウントにデプロイする場合はデフォルトで問題ありません。

Deploy in secondary region?

セカンダリーリージョンにAHAをデプロイするかを選択できます。もしAHAをマルチリージョンで利用する場合は追加するリージョンを選択してください。

ここを設定することで、DynamoDBのグローバルテーブルやLambdaなどがセカンダリーリージョンに展開されます。今回はシングルリージョンで展開するのでデフォルトのNoを選択します。

Exclude any account numbers?

アラートの対象として除外したいアカウントがあれば、カンマ区切りで区切ったアカウント番号のCSVファイルをaha-v1.8.zipと同じバケットにアップロードしてファイル名を指定します。今回は特に指定せずデフォルトのままにします。

今回設定した一覧を載せておきます。赤枠が変更した部分です。

あとは特に変更せず、AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。にチェックを入れてスタックを作成します。スタックが作成が完了すればAHAソリューションの展開は完了です。

通知の確認

実際に通知されるのかを確認していきます。AHAを展開してから1日放置したところ、ちょうどよく以下の障害が起きて通知が来ていました。

障害発生時はStatusがopenとなり、対象のサービスや、Updateを見るとどのような障害が起きているのかを確認できます。

その後、障害が解消されたタイミング(Status:closed)でも改めて通知が来ました。Slackの場合は障害時に赤ライン、解消時は緑ラインで表現されているのが分かりやすくていいですね。

今回は確認できませんでしたが、パブリックではなくアカウント固有のイベントが発生した際には、影響があるアカウントとリソースも確認できるようです。

AHAの削除

もしAHAを削除する場合は、CloudFormationスタックとコードをアップロードしたS3バケットを削除してください。

マルチリージョンで展開する場合

マルチリージョンで展開するときは若干手順が違います。前準備としてS3バケットとコードのアップロードは同じように行ってください。

まず、StackSetsで利用するIAMロールを以下のテンプレートをダウンロードしてCloudFormationから作成します。

2つのロール作成が完了したら、シングルリージョンの時と同じようにテンプレートのアップロードからCFN_DEPLOY_AHA.ymlをアップロードして次へ進みます。パラメータを入力していくのですが、シングルリージョンの時と違うのはDeploy in secondary region?のパラメータでセカンダリとしたリージョンを選択することです。

ここでセカンダリを追加すると、DynamoDBのグローバルテーブルが作成されるのと、DynamoDB以外のリソースをStackSetsからセカンダリリージョンに展開してくれます。

東京リージョンで作成されるリソースにAHASecondaryRegionStackSetが追加されています。

指定したセカンダリのリージョンを確認すると、以下のようなスタックが展開されていました。

マルチリージョンからシングルリージョンに変更したい場合

もし変更したくなった場合は、マルチリージョンとして展開したスタックからセカンダリとして入力したDeploy in secondary region?のパラメータをNoに変更してください。セカンダリに展開されたリソースが削除され、シングルリージョンになります。

まとめ

AWS Health Aware (AHA)を利用して、HealthOrganizational Viewのイベントログの情報をSlackに通知してみました。AHAのソリューションは手軽に展開でき、組織内全てのイベントを手軽に通知させることができます。Organizationsでマルチアカウントを運用されている方は一度検討してみてはいかがでしょうか?

参考