API destinations とは、EventBridge から直接 HTTP エンドポイント へ送信できる機能です。
Typetalk とは、Nulab 提供のチャットサービスです。
AWSで発生したイベントを Typetalk に流します。
Typetalk
Nulab製品同士であればシームレスに連携できますが、他サービスの場合はボット機能で連携させます。
ボットの作成
"トピックメニュー" -> "トピック設定" -> "ボット" -> "新規追加" から作成します。
ボットに発言させるので、 topic.post
を有効にします。 デフォルト有効です。
トークンの取得
ボットを作成すると、 "Typetalk Token" と "メッセージの取得と投稿の URL" が払い出され、これらを使用してアクセスすることになります。
記述方式として2パターン使えます。
- 認証と認可 | Typetalk Developer API | Nulab
- ヘッダ
X-Typetalk-Token: YOUR_TYPETALK_TOKEN
- "メッセージの投稿コマンドサンプル" はこちらの形式になっています。
- パラメータ
typetalkToken=YOUR_TYPETALK_TOKEN
- 例:
https://typetalk.com/api/v1/topics/xxxxx?typetalkToken=YOUR_TYPETALK_TOKEN
- 例:
- ヘッダ
Amazon EventBridge
AWSマネジメントコンソールから作成する場合、作成ウィザードが統合されており、 rule の作成から併せて作成することもできます。
個別に作成する場合は、 Connection、API destination、Rule の順で作成していきます。
Connection 作成
Amazon EventBridge -> API destinations -> Connections から作成します。
- Destination type:
Other
- サポートされているパートナーであれば Partners から選択し、必要パラメータが埋まった状態になりますが、Otherでは全て自前で設定してく形となります。
- Authorization type:
API Key
API key は Secrets Manager に設定されます。
# Secret name: `events!connection/{API destination name}/xxxxx` {"api_key_name":"X-Typetalk-Token","api_key_value":"YOUR_TYPETALK_TOKEN"}
API destination 作成
Amazon EventBridge -> API destinations から作成します。
- API destination endpoint:
https://typetalk.com/api/v1/topics/xxxxx
- Typetalkで作成した "メッセージの取得と投稿の URL" を指定します。
- HTTP method:
POST
- Use an existing connection:
- 作成済みの Connection を指定します。
Rule 作成
Amazon EventBridge -> Rules から作成します。
- Target types:
EventBridge API destination
- API destination:
- 作成した API destination を指定します。
- Execution role:
- IAM Role が自動生成されます。事前に作成しておき選択することもできます。
Additional settings を開き、追加設定を行います。
- Configure target input:
Input transformer
- "Configure input transformer" を押下し、変換設定を行います。(後述)
- Dead-letter queue:
- 配信に失敗した場合にキューに残せます。設定する場合、SQSは事前に作成しておく必要があります。
- 参考: Event retry policy and using dead-letter queues - Amazon EventBridge
Execution role について
自動生成される IAM Role のポリシーは以下の通りです。
Trust relationship
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "events.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Permission
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "events:InvokeApiDestination" ], "Resource": [ "arn:aws:events:ap-northeast-1:123456789012:api-destination/{API Destination Name}/*" ] } ] }
Configure input transformer 設定
Amazon EventBridge input transformation - Amazon EventBridge
EventBridge で受信した Event を Typetalk へ送信するための形式に変換します。
Event により大きく変わるため、細かな部分を省きますが今回の設定例は以下の通りです。
input path
"Security Hub Findings - Imported" Event を題材にします。
{ "Account": "$.account", "Description": "$.detail.findings[0].Description", "DetailType": "$.detail-type", "FirstSeen": "$.detail.findings[0].FirstObservedAt", "LastSeen": "$.detail.findings[0].LastObservedAt", "Recommendation": "$.detail.findings[0].ProductFields.RecommendationUrl", "Region": "$.region", "Resource": "$.detail.findings[0].Resources[0].Id", "Severity": "$.detail.findings[0].Severity.Label", "Summary": "$.detail.findings[0].Title" }
Input template
メッセージを投稿する | Typetalk Developer API | Nulab
Typetalk に投稿するため、 { "message": "" }
の形式にします。
{ "message": ":warning: [<Severity>] <DetailType> | <Region> | Account: <Account>\n\n<Summary>\n> <Description>\n```\nFirst Seen: <FirstSeen>\nLast Seen: <LastSeen>\nAffected Resource: <Resource>\nSeverity: <Severity>\nRecommendation: <Recommendation>\n```" }
通知確認
正しく設定が行われていれば、AWS上での Event 発生時に Typetalk へ投稿されます。
AWS Chatbot での Slack 通知に似せ、且つ、使える書式を全て使ってみました。
Typetalk
Slack (Chatbot)
まとめ
Terraform 化した物を以下に置いてます。
Typetalk ではトピック毎にボットを設定し、ボット毎にAPI Keyが払い出される仕様であるため、 複数トピックを運用したい場合は一連のリソースをそれぞれ作成する必要があります。
API destination の Endpoint にパラメータ形式で API Key を直接埋め込む事も可能ですが、Secrets Manager 統合が成されているのでヘッダ形式での設定がお薦めです。
余談
普段は Slack + Chatbot を利用しており、API destination を使う機会が無かったのですが、 これまで EventBridge -> SNS Topic -> Lambda Function などで処理していた部分を EventBridge(API destination + Input transformer) 単体で管理できるのは良いと思いました。
受信したイベントそれぞれに対応して Input transformer で変換を掛けていかないとならないのが難点です。
Chatbot で大部分のイベントをサポートしているので、その整形部分を利用できるようになるとまた変わってくるかもしれません。 現状、正常の場合はログにもイベントは残らないようなので期待薄でしょうかね。