はじめに
AWSのCloudWatchのメトリクスを、DatadogやNew Relic、Mackerelなどの監視のSaaSに連携する方法について、各種SaaSツールで提供されているAWS Integration系の機能を利用しているとメトリクス連携の遅延やCloudWatchのAPI利用のコストが課題になることがあります。今回はメトリクス遅延の発生する原因と、CloudWatch Metric Streamsを使った対策の一例を紹介します。
各種監視系SaaSのAWS Integration機能の遅延&コスト課題
監視内容によってAWSの情報を前述のような監視系SaaSツールに連携する方法は様々ですが、AWS上の各リソース状況をCloudWatchメトリクス経由でSaaSに連携する場合、SaaSツール側で提供されるAWS Integrationなどの機能を有効化して連携するケースが多いかと思います。このAWS Integration機能では、大半がSaaSツール側から監視対象のAWSアカウントのCloudWatch APIを一定間隔でポーリング実行してメトリクスを取得する方式になっています。
例えばDatadogのAWS Integrationでは、10分ごとにCloudWatchのGetMetricDataなど複数のAPIをポーリングして連携を行っています。
Datadog の AWS インテグレーションは、どのように CloudWatch を使用していますか?
Datadog は CloudWatch モニタリング API を使用して、AWS リソースを監視しています。これらの API の主な使用方法は、GetMetricData エンドポイントを通じて生のメトリクスデータを収集することです。
その他の API は、メトリクスデータを充実させるために使用されます。いくつかの例を挙げます。
- メトリクスに追加するカスタムメトリクスタグを収集する
- 自動ミュートなど、リソースのステータスや 健全性に関する情報を収集する
- ログストリームを収集する
API リクエストの回数と、CloudWatch の使用量はどのように把握できますか?
Datadog は、インストールした各 AWS サブインテグレーションについて、利用可能なメトリクスを 10 分ごとに収集します。特定のサブインテグレーション (SQS、ELB、DynamoDB、AWS カスタムメトリクス) に対して多数の AWS リソースを持っている場合、AWS CloudWatch の請求に影響を与える可能性があります。
上記の公式ページのFAQにも記載がありますが、上記のような方式のため以下の課題があります。
- メトリクス連携の遅延
- 一定間隔でのAPIポーリングする方式のため、対象のSaaSツール上に実際のメトリクスが連携されるまで、AW上の対象リソースからCloudWatchに連携される時間に加えてAPIポーリング間隔分の時間が遅延する。
- CloudWatchのコスト増加
- 複数リソースに対して定期的にCloudWatchの各種APIを実行するため、CloudWatchの請求額が増加
特にメトリクス連携の遅延は、監視対象のメトリクスによっては検知アラートや対応が遅れてしまうことに繋がるため、対処したいケースが多いかと思います。
CloudWatch Metric StreamsとKinesis Data Firehose経由でメトリクスを連携する
上記のような課題への対処方法として、SaaS側からCloudWatch APIをポーリングする方法ではなく、AWS側からSaaS側にストリームで流し込む方式により改善が見込めます。具体的には以下のようにCloudWatchのメトリクスをCloudWatch Metric Streams及びKinesis Data Firehoseを使ってStreamでSaaS側のHTTPエンドポイントに流し込むようなイメージとなります。
Datadogではこの構成のスタックを作成するCloudFormationを提供しています。今回はDatadogやAWSの各種リソースをすでにTerraformで管理しているケースを想定して、Terraformでの実装イメージを紹介します。なお事前にTerraform上でのAWS Providerの設定ができていることを想定しています。
まずCloudWatch Metric Streamsについては、以下のようなイメージになります。include_filterはmetric filterを使う場合namespaceを必要に応じて設定してください。
resource "aws_cloudwatch_metric_stream" "datadog" {
name = "datadog-stream"
role_arn = aws_iam_role.metric_stream_to_firehose.arn
firehose_arn = aws_kinesis_firehose_delivery_stream.datadog_stream.arn
output_format = "opentelemetry0.7"
# 必要があれば設定
include_filter {
namespace = "AWS/EC2"
}
}
# https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-metric-streams-trustpolicy.html
data "aws_iam_policy_document" "metric_stream_to_firehose" {
statement {
effect = "Allow"
actions = [
"firehose:PutRecord",
"firehose:PutRecordBatch",
]
resources = [aws_kinesis_firehose_delivery_stream.datadog_stream.arn]
}
}
destinationにはhttp_endpointを設定して、Datadogの設定を行います。
resource "aws_kinesis_firehose_delivery_stream" "datadog_stream" {
name = "cw-to-datadog-stream"
destination = "http_endpoint"
http_endpoint_configuration {
name = "Datadog"
access_key = var.datadog_api_key // Datadog APIキーを発行して設定
role_arn = aws_iam_role.datadog_firehose.arn
url = var.datadog_firehose_endpoint // Datadog側から確認して設定
request_configuration {
content_encoding = "GZIP"
}
}
}
さいごに
今回はCloudWatch Metric StreamsとKineis data Firehoseを使ってSaaS監視ツールのメトリクス遅延に対処する方法をTerraformのコード例とともに紹介しました。今回のStreamで流し込むことで、Datadogで10-15分程度の遅延が発生していたCloudWatchメトリクスの連携が、ほぼリアルタイムでDatadog側に連携することができました。