CloudWatch Logs に出力した Aurora の監査ログを、異なる AWS アカウントの CloudWatch アラームを使って監視・通知する。

記事タイトルとURLをコピーする

概要

以下の記事で、Aurora の監査ログ (pgaudit) をCloudWatch Logs に出力して、ログアーカイブ用の AWS アカウントの S3 バケットに保管しました。
blog.serverworks.co.jp

本記事では、CloudWatch Logs に出力した Aurora の監査ログ (pgaudit) を、異なる AWS アカウントの CloudWatch アラームを使って監視・通知してみます。
「異なる AWS アカウント」については、監視用の CloudWatch アラームや、通知用の SNS を集中管理するような AWS アカウントを想定しています。 本記事は CloudWatch Logs に出力した Aurora の監査ログを対象としているものの、CloudWatch Logs に出力しているログなら、同じことが出来ます。
構成図は以下となります。

処理概要としては以下となります。

  • Aurora がある AWS アカウント側
    1. Aurora が 監査ログ (pgaudit) を CloudWatch Logs に出力
    2. CloudWatch Logs のメトリクスフィルター機能を用いて、特定の文字列を検知しメトリクスとして記録する
      • 例:SELECT * FROM TABLE; の SQL を 1 回実行すると監査ログ (pgaudit) に記録し、CloudWatch Logs に出力する。CloudWatch のメトリクスフィルターが検知し、メトリクス 1 を記録する
  • 監視用の CloudWatch アラームのある、異なる AWS アカウント側
    1. 共有を受けているメトリクスが 1 以上になると CloudWatch アラームがアラーム状態になる
    2. アラーム状態になったため、SNS 経由でユーザーにメールを送信する

CloudWatch のクロスアカウントオブザーバビリティ機能を利用して、AWS アカウント間でログやメトリクスを共有することが可能なため、上記の構成、処理を作成できます。

なお制約として、CloudWatch Logs に保管するログから特定の文字列を検知するメトリクスフィルター機能については、異なる AWS アカウント側では作成できません。(2024/06/05 現在)もし、異なる AWS アカウント側でログの共有を受けていても、メトリクスフィルターを作成できません。そのため、Aurora がある AWS アカウント側にメトリクスフィルターを作成しています。

CloudWatch のクロスアカウントオブザーバビリティ

CloudWatch のクロスアカウントオブザーバビリティ機能を使用すると、ログやメトリクスを他の AWS アカウントから参照できます。
参照する側の AWS アカウントを「モニタリングアカウント」と呼んでいるようです。
「モニタリングアカウント」で参照可能なものは以下です。

  • Amazon CloudWatch のメトリクス。すべての名前空間のメトリクスをモニタリングアカウントと共有できるほか、フィルターで一部の名前空間に絞り込むことができます。
  • Amazon CloudWatch Logs のロググループ。すべてのロググループをモニタリングアカウントと共有できるほか、フィルターで一部のロググループに絞り込むことができます。
  • AWS X-Ray のトレース
  • Amazon CloudWatch Application Insights のアプリケーション
  • CloudWatch Internet Monitor でのモニタリング

参考:
CloudWatch のクロスアカウントオブザーバビリティ

料金については基本的には無料です。X-Ray のトレースを2つ以上のモニタリングアカウントから参照する際に、2つ目以降のモニタリングアカウントにトレースをコピーする料金がかかります。

クロスアカウントオブザーバビリティでは、ログやメトリクスの追加料金が発生しません。CloudWatch は、最初のモニタリングアカウントに保存された最初のトレースコピーを追加料金なしで提供します。追加のモニタリングアカウントに送信されたトレースコピーは、AWS X-Ray の料金に基づいて、記録されたトレースのソースアカウントに請求されます。CloudWatch Dashboards、アラーム、Logs Insights クエリなど、モニタリングアカウントで使用する機能については、CloudWatch の標準料金が適用されます。

参考: 料金 - Amazon CloudWatch | AWS

CloudWatch のクロスアカウントオブザーバビリティでメトリクスやログを共有する方法

Organizations に所属していない、ある一つの AWS アカウントのメトリクスやログを、同様のモニタリングアカウントから参照する方法を例示します。
条件が異なる場合は以下のリンクを参照ください。
モニターリングアカウントをソースアカウントにリンクする - Amazon CloudWatch

モニタリングアカウント側の作業

CloudWatch のサービス画面の左下にある「設定」画面にいきます。

「4. モニタリングアカウントでクロスアカウントデータを閲覧する」の「設定」ボタンを押します。

「データを選択」枠には、モニタリングアカウントで参照するものにチェックを入れます。 また、「ソースアカウントを一覧表示」枠には、Aurora がある AWS アカウント側のアカウント番号を入力します。

「設定」ボタンを押します。

設定が正常にできると、「アカウントをリンクするためのリソース」というボタンが出てくるので押します。

CloudFormation テンプレートをダウンロードします。

Aurora がある AWS アカウント側の作業

CloudFormation のサービス画面から、新しいスタックを作成し、先程の CloudFormation スタックをアップロードし、実行します。

CREATE_COMPLETE になりました。

モニタリングアカウント側での確認

CloudWatch メトリクスの画面に Aurora がある AWS アカウント側 の アカウント ID のメトリクスが表示され、参照できるようになりました。

メトリクス同様に、ロググループも表示され、参照できるようになりました。モニタリングアカウントのログの場合、アカウントラベルは「モニタリングアカウント」になっています。

モニタリングアカウントでログやメトリクスを参照する際の注意点

共有を受けているメトリクスについては、自身のメトリクスと同様に、CloudWatch アラーム を作成できます。

一方、共有を受けているログについては、メトリクスフィルター、サブスクリプションフィルター、異常検出の項目を設定できません。

上記の制約があるため、CloudWatch Logs に保管するログから特定の文字列を検出するメトリクスフィルターは、Aurora がある AWS アカウント側に作成します。(2024/06/05 現在)
Aurora がある AWS アカウント側にメトリクスフィルターを作成し、メトリクスを記録します。
モニタリングアカウントではメトリクスの共有を受けます。
共有を受けているメトリクスについて、モニタリングアカウント側で、CloudWatch アラームを作成します。

Aurora がある AWS アカウント側に、CloudWatch Logs に保管するログから特定の文字列を検出するメトリクスフィルターを作成する

メトリクスフィルターを作成する

Aurora がある AWS アカウント側で、監査ログ (pgaudit) を出力している CloudWatch Logs のロググループを選択します。
「アクション」より「メトリクスフィルターを作成」を押します。

テストとして2つの SQL を実行した際に検知するメトリクスフィルターを作成します。

  1. SELECT * FROM pg_extension
  2. SHOW shared_preload_libraries

参考としまして、監査ログのレコード例です。

2024-06-05 04:24:29 UTC:10.0.15.24(44510):postgres@postgres:[713]:LOG: AUDIT: SESSION,1,1,READ,SELECT,,,SELECT * FROM pg_extension;,<not logged>

CloudWatch Logs 画面:

監査ログ (pgaudit) には、実行した SQL よりも前に、:LOG: AUDIT: という文字列を含みます。
正規表現が使えるものの、サブパターンは使えないので、以下のような表現になりました。

%^.*:LOG: AUDIT:.*SELECT \* FROM pg_extension.*$|^.*:LOG: AUDIT:.*SHOW shared_preload_libraries.*$%

2つのログを表す表現を、真ん中のパイプで区切って or 条件にしています。
メトリクスフィルターは1つのロググループあたり100個作れるので、2つ作っても良いと思います。本記事では検証ということもあり、1つにしました。
参考:CloudWatch ログクォータ - Amazon CloudWatch Logs

SELECT * の「*」については、バックスラッシュでエスケープしています。
メトリクスフィルターで正規表現を使用する際には、前後を「%」で囲うようです。

参考:サポートされている正規表現 (regex) 構文

上の正規表現を入力し、必要に応じてパターンをテストし、「Next」を押します。なお、上の正規表現パターンはテストボタンで検知できました。

任意のフィルター名を付けます。

「メトリクス名前空間」は「pgaudit」とし、「メトリクス名」には Aurora のクラスター名が分かる名前を入れました。複数のクラスターがある場合にも分かりやすい名前にすると良いでしょう。メトリクス値は 1 としました。これで、対象の SQL を実行すると、メトリクス 1 を記録するようになります。Unit は「カウント」にしました。

メトリクスフィルターを作成します。

作成できました。

CloudWatch のサービス画面を見てみましょう。
対象の SQL を実行すると、CloudWatch にメトリクスが出ていました。

最小期間は1分毎のようで、その間に2回 SQL を実行した際には、メトリクスが 2 にカウントアップされていました。

モニタリングアカウントの CloudWatch アラームを使って監視・通知する。

モニタリングアカウント側に CloudWatch アラームを作成する

pgaudit 名前空間のメトリクスが、モニタリングアカウントのCloudWatch メトリクスに共有されていることを確認します。

参照できます。

「アクション」の枠内にあるベルマークのボタンを押して、アラームを作ります。

1 分間に1 回以上、対象の SQL を実行するとアラーム状態になるようにします。

テスト用の SNS トピックに通知します。

分かりやすい名前を付けて、アラームを作成します。

対象の SQL を実行すると、アラームの通知が来ました。

まとめ

CloudWatch のクロスアカウントオブザーバビリティ機能を使用すると、ログやメトリクスを他の AWS アカウントから参照できます。 他のアカウント側で CloudWatch アラームを作成することもできます。
CloudWatch のアラームや、SNS トピックを共通的に使いたい場合にも、この機能は便利だと感じました。
本記事は CloudWatch Logs に出力した Aurora の監査ログを対象としているものの、CloudWatch Logs に出力しているログなら、同じことが出来ます。

余談

山梨にある笊ヶ岳という、難易度の高い山をトレイルランニングしてきました。
標高 500 m の登山口を出発した後、ひたすら急な登りが続く山で、標高 2500 m くらいまで延々に登ります。
ルート上も危険箇所が多く、あまりおすすめできないものの、山頂からは南アルプスの山々が見えて癒やされました。

山本 哲也 (記事一覧)

カスタマーサクセス部のエンジニア(一応)

好きなサービス:ECS、ALB

趣味:トレラン、登山(たまに)