こんにちは、インフラエンジニアの小林です。
今回は、CloudWatch Metric Mathを使用したメトリクスの検索機能を解説し、そのメトリクスを使用したダッシュボードのTerraformでのサンプルコードをご紹介します。
はじめに
LCLでは AWS WAFのマネージドルールを使用し、悪意のあるリクエストからサービスを保護しています。
マネージドルールは簡単な設定で強力にサービスを保護してくれますが、ユースケースによっては誤検知の危険があります。現状、誤検知は発生していませんが、将来的にマネージドルールが更新された時などに、誤検知が増える可能性があります。
そのため、各マネージドルールがブロックしたリクエスト数を CloudWatch ダッシュボードで可視化し、何か問題があったときにすぐに気付けるようにしました。
また、CloudWatch ダッシュボードで表示するにあたり、今回のような複数のグラフを絞り込むために、Metric Math という機能を使用しました。
なお、ダッシュボードとは別に CloudWatch Aram を使用した slack 通知も作成しましたが、長くなりますので別記事にて紹介いたします。
Metric Mathとは?
CloudWatchのさまざまなメトリクスを、SQLのような構文でクエリできる機能です。
Metric Mathを利用することで、さまざまのメトリクスの合計や平均などを簡単に検索することができます。
Metric Mathの検索クエリの基本構文
Metric Math の基本的な構文は以下のようになります。
SEARCH(' {Namespace, DimensionName1, DimensionName2, ...} SearchTerm', 'Statistic')
SEARCH
: 検索をするための Metric Math の関数です。SEARCH
の 引数は、シングルクォートで囲った2つの文字列です。(ぱっと見、もっと引数があるように見えてややこしいですね)- 1つ目の引数は、
{}
で囲ったところ{Namespace, DimensionName1, DimensionName2, ...}
と、SearchTerm
があります。 -
{}
で囲ったところは、カンマ区切りで 名前空間(Namespace) と、 ディメンジョン を指定します。- 名前空間 とは、各メトリクスの大まかな分類です。 AWS/EC2 のように、サービスごとに分類されています。また、カスタムの名前空間も作ることができます。
- ディメンジョン とは、各メトリクスをが持つ固有の情報で、 SearchTerm にてメトリクスを絞り込むために使用します。
- 例えば、EC2であれば、
InstanceId
や、InstanceType
などを持っています。
SearchTerm
には、検索条件を入力します。次章の Metric Math のクエリ例 で解説いたします。- Statistic には、どのように統計を取るかを入力します。合計なら Sum 、平均ならば Average があります。
Metric Math のクエリ例
以下は、特定のWebACLの、複数のマネージドルールがブロックしたリクエストを探すクエリの例です
SEARCH(' {AWS/WAFV2,Rule,WebACL,Region} Rule=( “managed-rule-a” OR “managed-rule-b” OR “managed-rule-c” ) WebACL="web-acl-name” Region="${data.aws_region.current.name}" MetricName=( "BlockedRequests" ), 'Sum')
{AWS/WAFV2,Rule,WebACL,Region}
AWS/WAFV2
メトリクスを取る名前空間です。Rule,WebACL,Region
絞り込み対象のディメンジョンです。
SearchTerm
Rule=...
: 表示したいルールを絞り込んでいます。複数あるため、OR 検索をしています。WebACL=...
: 表示したいWebACLを絞り込んでいます。Region=...
: 表示したいリージョンを絞り込んでいます。(何も書かないとデフォルトリージョンで絞り込んでくれることを期待しましたが、エラーが出ました)MetricName=...
: 対象のどのメトリクスを取るかを決定します。今回はブロックしたリクエストを計測したいので、BlockedRequests
を指定します。
Statistic
- 今回は、合計値を知りたいので、
Sum
を指定します。
- 今回は、合計値を知りたいので、
ここまでで、Metric Mathを使用したメトリクスの検索方法を解説いたしました。 ここからは、上記のクエリを組み込んだダッシュボードを表示するTerraformのサンプルコードを紹介いたします。
Metric Mathで検索したメトリクスを表示するダッシュボードのTerraformのサンプルコード
locals { blocked_managed_rules_expression_base = <<-EOS SEARCH(' {AWS/WAFV2,Rule,WebACL,Region} Rule=( “managed-rule-a” OR “managed-rule-b” OR “managed-rule-c” ) WebACL="web-acl-name” Region="${data.aws_region.current.name}" MetricName=( "BlockedRequests" ), 'Sum') EOS blocked_managed_rules_expression = join(" ", split("\n", local.blocked_managed_rules_expression_base)) } resource "aws_cloudwatch_dashboard" "waf_dashboard" { dashboard_name = "waf_dashboard" dashboard_body = jsonencode({ widgets = [ { type = "metric", x = 0, y = 0, width = 24, height = 6, properties = { metrics = [ [ { period = 3600, expression = local.blocked_managed_rules_expression } ] ], region = data.aws_region.current.name, title = "Blocked by managed rules" stacked = true } ] }) }
簡単な解説
aws_cloudwatch_dashboard
の dashboard_body に、ダッシュボードの設定をJSONで定義します。metrics
のexpression
で、実際に検索したい Metric Math のクエリを設定します。ここに直接クエリを書くと、視認性が下がりそうでしたので、locals にクエリを分離しています。また、視認性を上げるためにクエリをヒアドキュメントで書いていますが、Metric Math に改行を入れることはできなかったので、後から削除しています。metrics
のperiod
では、メトリクスの時間区切りを定義します。今回の場合は、1時間ごとのブロック数の合計が表示されますstacked = true
にて、複数のメトリクスが重なって表示されます。これにより、マネージドルール全体でどれだけブロックしたかを可視化できます
最後に、上記の設定にて実際に作成されたメトリクスのスクリーンショットを紹介いたします。 どのマネージドルールがどれだけブロックしたかと、全体でどれだけブロックしたかの両方が素早く把握できるグラフができ上がりました。
まとめ
CloudWatch の Metric Math は、クエリを使うことでかなり自由にグラフを作成することができます。
本記事が皆様の監視業務の一助になりましたら幸いです。
参考
- https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups.html
- https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/search-expression-syntax.html
- https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/using-metric-math.html
- https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/cloudwatch_concepts.html