2021/3/5(日本時間)に EventBridge から外部の HTTP エンドポイントを叩けるアップデートがありましたので、Lambda なしで Slack への通知ができそうだったのでやってみました。
AWS のマネジメントコンソールにログインした際に Slack に通知したい、というニーズは結構あるのではないかと思います。2020年に AWS Chatbot が登場し、CloudWatch Event から SNS へ通知し、Chatbot でサブスクリプションしてやることで簡単に Slack への通知ができるようになりましたが、残念ながら コンソールログインイベントは Chatbot に対応していません。 コンソールログインイベントを Slack に通知するには、EventBridge(CloudWatch)でのログインイベントをトリガーに Lambda を起動し、Web Hook を通じて通知させるというやり方が一般的でした。
EventBridge のアップデートにより Lambda がなくても Web Hook を呼び出すことができるようになったので、その際の設定を記録として残しておきたいと思います。
構成
アーキテクチャとしては、描くほどでもありませんが以下のようになります。マネジメントコンソールにログインしたタイミングで発生したイベントをトリガーに EventBridge から直接 Slack に通知します。
事前準備
事前に Slack アプリ( https://api.slack.com/apps )から Webhook の URL を作成しておきます。
私はこちらの投稿を参考にさせていただきました : https://qiita.com/kshibata101/items/0e13c420080a993c5d16
手順
ざっくりとした手順は以下のようになります。
- EventBridge から
API の送信先
と接続
を設定します - EventBridge から
ルール
を作成します
たったこれだけでいけます。
1. EventBridge から API の送信先と接続を設定
では早速設定していきます。
- マネジメントコンソールから Amazon EventBridge を開きます
- 左メニューから、「API の送信先」を選択します
- 「API 送信先を作成」をクリックします
- API 送信先の詳細で「名前」に任意の名前を入れます
- 「API 送信先エンドポイント」には Slack アプリで作成した Webhook の URL を入力します
- 「HTTP メソッド」には
POST
を指定します - 「1 秒あたりの呼び出しレート制限」では送信先の制限や性能を考慮して設定します。今回の例では個人的な利用なので 1 で問題ないと判断しました
- 「接続」では
新しい接続を作成
を選択します - 続いて「接続名」に任意の名前を入力します
- 「認証タイプ」は、認証なしというのがないようなので
API キー
として適当な名前と値を指定しておきます - 「呼び出し Http パラメータ」は設定不要です
- 「作成」 をクリックします
これで API の送信先と接続先が作成できました。
2. EventBridge からルールを作成
続いて、EventBridge からルールを作成します。ルールではマネジメントコンソールへのログインイベントをキャッチするようにしたり、発生したログインイベントに対して実行するアクション(今回の場合 Slack への通知)を設定します。
- EventBridge の左メニューから「ルール」を選択します
- 「ルールを作成」をクリックします
- 「名前」にルールの名前を入力します
- 「パターンを定義」では以下のように設定します
イベントパターン
を選択- イベント一致パターンでは
サービスごとの事前定義パターン
- サービスプロバイダーは
AWS
- サービス名は
AWS コンソールのサインイン
- イベントタイプは
サインインイベント
任意のユーザー
を選択
- 「イベントバスを選択」はデフォルトのままにします
- 「ターゲットを選択」では以下のようにします
- ターゲットは
API 送信先
- API 送信先は
既存の API 送信先を選択
- ヘッダーパラメータはデフォルトのまま
- クエリ文字列パラメータはデフォルトのまま
- 入力の設定は
入力トランスフォーマー
を選択します
ここで発生したイベントから必要な情報を取り出し、Slack のテンプレートに埋めこんでいきます入力パス
に以下のように入力($....
の部分はログインイベントの json 内でのパス)
{ "accountId": "$.detail.userIdentity.sessionContext.sessionIssuer.accountId", "sourceIPAddress": "$.detail.sourceIPAddress", "response": "$.detail.responseElements.ConsoleLogin", "eventTime": "$.detail.eventTime", "userName": "$.detail.userIdentity.sessionContext.sessionIssuer.userName" }
入力テンプレート
に以下のように入力(入力パスで設定したキーがプレースホルダーとして使えます)
{ "attachments": [ { "fallback": "AWS Console Sign In via CloudTrail", "pretext": "AWS Console Sign In via CloudTrail", "color": "#00DD00", "fields": [ { "title": "ConsoleLogin : <response>", "value": "*AWS Account* : <accountId>\n*User Name* : <userName>\n*IP Address* : <sourceIPAddress>\n*Event Time* : <eventTime>" } ], "footer": "by Amazon EventBridge - API Destination" } ] }
この特定のリソースに対して新しいロールを作成する
を選択してロールを新規に作成してもらいます- 「再試行ポリシーとデッドレターキュー」は今回は設定を省略します
- 必要に応じてタグを設定します
- ターゲットは
- 「作成」を選択します
手順としては以上です。
実行結果
実際に AWS マネジメントコンソールにログインした時に Slack に通知された時のイメージが下図になります。
AWS Chatbot が AWS のアイコンなので EventBridge のアイコンにしてみました。
まとめ
EventBridge の新しい機能、「API の送信先」を使うことで、プログラムを書くことなく HTTP エンドポイントにリクエストを送信することができるようになりました。「HTTP リクエスト送信」を行うプログラム、Lambda であれば大したコードではないかもしれませんが、書かずに済むのであればそちらの方が望ましいというシーンもなんだかんだ言ってもあるのではないかと思います。そんな現場での利用をご検討いただければと思います。
最後に・・・
この投稿は個人的なものであり、所属組織を代表するものではありません。ご了承ください。