CloudTrailでAWSリソース作成を検知して通知する

CloudTrail を用いてAWSリソース作成イベントを検知して通知してみたいと思います。
2019.06.10

こんにちは、吉井です。
いかがお過ごしでしょうか。
"No human labor is no human error" が大好きな吉井です。

2019年6月4日に弊社主催セミナーでコスト最適化についてお話させて頂きました。
(セミナー資料は こちら )

私のパート中に「野良サーバーを作られないように気をつけましょう」といった内容の発言をしたところ、
参加者の方から「EC2 のようなコストに即反映するサービスは解るが、Lambda や API Gateway のように使ってみないと課金されないサービスはどうするのか?」といった質問を頂戴しました。

今回は CloudTrail を用いてリソース作成イベントを検知して通知してみたいと思います。
例として Lambda 関数の作成を検知します。
他サービスの検知をご希望の場合は読み替えて頂ければ幸いです。

CloudTrail の設定

まずは CloudTrail を設定していきます。
マネジメントコンソールに管理者権限でログインし、CloudTrail を開きます。

左ペインから 証跡情報 をクリックします。

証跡情報を入力していきます。

証跡情報の作成

項目
証跡名 識別しやすい任意の名前を入力
証跡情報を全てのリージョンに適用 はい

管理イベント

項目
読み込み/書き込みイベント すべて

データイベント

本エントリでは何も設定しません。
S3 オブジェクトレベルのアクティビティや Lambda 関数の実行レベルのアクティビティを取得したい場合に設定してください。

ストレージの場所

項目
新しい S3 バケットを作成しますか はい
S3 バケット 識別しやすい任意の名前を入力
ログファイルのプレフィックス プレフィックスを付けたい場合は入力、必須ではありません
SSE-KMS を使用してログファイルを暗号化 本エントリでは いいえ にします
ログファイルの検証を有効化しますか。 はい
ログファイル配信のたびに SNS 通知を受け取りますか いいえ

CloudTrail to CloudWatch Logs

作成したばかりの証跡情報を開きます。
画面を下へスクロールすると、CloudWatch Logs の項目があります。

そのなかにある 設定 ボタンをクリックします。

項目
新規または既存のロググループ デフォルトのまま (CloudTrail/DefaultLogGroup)

ロググループ名を入力したら 次へ をクリックします。

CloudTrail が CloudWatch Logs へ書き込みするためのロール作成画面が表示されます。
新しい IAM ロールの作成 を選び、任意の名前を付けます。
許可 をクリックします。

設定が終わりました。

2019/06/11 追記
CloudWatch Events でも本エントリと同様の通知は可能です。
今回例にしている Lambda 関数作成 API は「CreateFunctionYYYYMMDD」のように末尾にバージョンが付与されます。
ここを柔軟に拾いたいという意図から CloudWatch Logs 経由で検知する方法を紹介しています。
ご了承頂けると助かります。

SNS 設定

通知を行うための SNS を設定していきます。
今回は比較的簡単なメール通知を行います。

トピック作成

同じく管理者権限で トピック を開きます。

トピックの作成 をクリックします。

任意の名前を入力してトピックを作成します。

サブスクリプション作成

トピックが作成された画面そのままで サブスクリプションの作成 をクリックします。

<サブスクリプションの作成>画面では以下を入力して サブスクリプションの作成 をクリックします。

項目
トピック ARN 表示されているまま
プロトコル E メール
エンドポイント 通知先メールアドレス

しばらくすると、AWS Notification - Subscription Confirmation という件名のメールが送付されてきます。 文中にある Confirm subscription を開いて Confirm してください。

下の例のようにステータスが 確認済み になれば完了です。

CloudWatch Logs 設定

同じく管理者権限で CloudWatch Logs を開きます。

メトリクスフィルタ 設定

前の手順で設定したロググループ (デフォルトのままなら CloudTrail/DefaultLogGroup) が出来ています。
メトリクスフィルタ列にある「nnフィルタ」をクリックします。

画面が遷移したら メトリクスフィルタの追加 をクリックします。

<ログメトリクスフィルタの定義>画面では、フィルタパターンに以下を入力し
メトリクスの割り当て をクリックします。

{$.eventSource = "lambda.amazonaws.com" && $.eventName = "CreateFunction*" }

<メトリクスフィルタの作成とメトリクスの割り当て>画面では
メトリクス名 に任意の名前を入力して、フィルタの作成 をクリックします。

アラーム作成

作成したメトリクスフィルタ欄にある アラームの作成 をクリックします。

<新しいアラームの作成>画面では、アラーム詳細を以下のように設定します。

項目 設定値
名前 識別しやすい名前
説明 説明文を入力します
>= 1
期間 1 / 1

アクションを以下のようにします。

項目 設定値
アラームが次の時 状態: 警告
通知の送信先 前の手順で作成した SNS トピック

作成されたことが確認出来ます。

テスト

それではテストをしてみます。
プリセットの関数を拝借して HelloWorld を作ってみました。

しばらく待つことにします。
メールで通知されました。

ログの確認

もう少し詳細に確認したいですね。
CloudWatch Logs を開きます。

ロググループのなかから CloudTrail/DefaultLogGroup をクリックします。

イベント検索 をクリックします。

イベントのフィルター欄に以下を入力します。

{$.eventSource = "lambda.amazonaws.com" && $.eventName = "CreateFunction*" }

検索してみるとログを確認出来ます。
何度か試したので3件表示されています。
これを展開すれば詳細が表示されています。

他サービスにも

CloudTrail サポートされるサービスと統合 を参照して通知したい API コールを設定してみてください。
CloudWatch Logs のメトリクスフィルタを変えるだけで OK です。

参考

コンソールで証跡を作成および更新する
CloudTrail サポートされるサービスと統合