DatadogはAWSのCloudWatchメトリクスの取り込みをPull方式とPush方式の両方サポートしています。いわゆるDatadog AWS IntegrationはPull方式でCloudWatchメトリクスを10分程度のレイテンシーで取り込みます。一方で、AWS CloudWatch Metric StreamはPush方式でCloudWatchメトリクスをDatadogに3-5分程度のレイテンシーで取り込みます。
CloudWatch Metric Streamを使ったDatadogへのメトリクス送信について、Datadogが提供するCloudFormation StackをPulumiやTerraformから呼び出すメモです。
2025/03/28 追記
運用後の評価を書きました。
CloudWatch Metric Streamを使ってDatadogにメトリクスを送信するとは
DatadogはCloudWatch Metric Streamを使ったPush方式の記事を出しています。読むとモチベーションや構成が理解できます。記事中の図に加筆した「赤で囲んだ経路がPull方式」「青で囲んだ経路がPush方式」です。
Pull方式は、DatadogのAWSアカウントからクローラーでCloudWatch APIをたたく手法です。IAM RoleでDatadog AWSアカウントを許可しつつ権限を渡せば勝手に取り込んでくれる手放し感が便利かつ、DatadogのAWS Integrationから取り込むサービスを絞り込むことができます。AWSコストはCloudWatchの取得にかかり、Cost ExplorerでCW:GMD-Metrics
1として表示されます。Datadog自体はAWS Integrationで追加されるメトリクスにコストがかからないのですが、取り込むリージョンやサービスが多ければ多いほどAWS側のCloudWatchコストが増えます。リージョンやサービスは使っているものだけに絞ってコストを減らしましょう。
Push方式は、ユーザーがCloudWatch Metric StreamからFirehoseを経由してHTTP EndpointとしてDatadogにメトリクスを投げ込む手法です。複数のAWSサービスを設定しないといけずユーザーの手間が大きく、DatdogはCloudFormation Stackを提供しています。AWSコストはFirehoseとCloudWatchのメトリクスストリームにかかり、Cost ExplorerでCW:MetricStreamUsage
、Firehose:AWS-Out-Bytes
として表示されます。Pull方式と違ってメトリクスの平均値だけでなく、「最小、最大、サンプル数、合計」とより多くのメトリクスを収集します。このためリクエスト料金だけ見るとCW:MetricStreamUsage
はCW:GMD-Metrics
の3/10ですが、コストは1.5倍程度を見込むことになります。CWメトリクスストリームで全サービスを対象するのではなく、対象サービスを絞ってコストを減らしましょう。
以上をザクっと表にまとめます。
項目 | Pull方式 | Push方式 | 備考 |
---|---|---|---|
ユーザーが設定するもの | IAM Role | CloudWatch Metric Stream Firehose IAM Role CloudWatch Logs S3 |
|
公式提供の構築方法 | CloudFormation提供 | CloudFormation Stack提供 | |
AWSコストのUsageType | CloudWatch GMD-Metrics |
CloudWatch MetricStreamUsage Firehose AWS-Out-Bytes |
サービスやリージョンを絞ることでコストを抑えるとベター |
メトリクスの反映遅延 | 10-15min | 3-5min |
おおむね理解したところで、CloudWatch Metric Streamを使った仕組みを構築してみましょう。
CloudFormation Stackを使う
先に示した通りPull方式ではIAM Roleでしたが、Push方式は複数のAWSサービスを必要とします。このためDatadogが提供するCloudFormation Stackを使って構築するのが簡単かつ安定です。先に示したCloudWatch Metric Streamを使ったPush方式の記事にCloudFormationで展開する方法が書かれています。
Webから構築するならDatadogコンソール > Integration > AWS > 適当なアカウントを選択 > Metric Collectionの下部
を見るとAutomatically Using CloudFormationボタンがあります。
リンクをクリックするとCloudFormation Stackの作成画面が開くのでApiKey
とRegions
を入力すれば作成できます。
IaCからCloudFormation Stackを呼び出す
CloudFormationはいいサービスですが、すでにPulumiやTerraformを使っている場合は「IaCからCloudFormation Stackを呼び出す」とコード管理が一貫性を保てて好ましいでしょう。Pulumi/TerraformはCloudFormation Stackを簡単に呼び出せます。
Pulumi
CloudFormation Stackを呼び出すコードです。ここでは東京リージョン(ap-northeast-1)と米国東部リージョン(us-east-1)からメトリクスを送信する例です。割と素直なので、CloudFormation Stackは普段使っていないなら、IaCとCloudFormationを併用するより運用負荷は小さく感じます。
var config = new Config(); var datadogApiKey = config.RequireSecret("DatadogのAPIKey用のコンフィグキー"); var opt = new CustomResourceOptions(); _ = new Pulumi.Aws.CloudFormation.Stack($"datadog-metricstream-stack", new() { Name = "DatadogMetricStreams" TemplateUrl = "https://datadog-cloudformation-stream-template.s3.amazonaws.com/aws/streams_main.yaml", Capabilities = ["CAPABILITY_NAMED_IAM"], // CloudFormationの定義に合わせて指定する Parameters = new InputMap<string> { { "ApiKey", datadogApiKey }, { "DdSite", "datadoghq.com" }, // US1 { "Regions", ["ap-northeast-1", "us-east-1"] }, } }, opt);
Terraform
Terraformの場合はaws_cloudformation_stack
リソースで定義します。同じAPIで書けます。
resource "aws_cloudformation_stack" "datadog_metricstream_stack" { name = "DatadogMetricStreams" template_url = "https://datadog-cloudformation-stream-template.s3.amazonaws.com/aws/streams_main.yaml" capabilities = ["CAPABILITY_NAMED_IAM"] parameters = { ApiKey = var.datadog_api_key DdSite = "datadoghq.com" Regions = ["ap-northeast-1", "us-east-1"] } }
IaCを使ったCloudFormation Stackの注意
CloudFormation Stackを使うのはシンプル、かつほとんどのケースで十分でしょう。ただCloudFormation Stack起因の制約に3点引っ掛かることがあるので注意しましょう。
- IAM Roleの権限不足
- テンプレートのメトリクスストリームのInclude/Excludeの設定数上限
- Parameterの
DatadogApiKey
が毎回変更差分と検出
IAM Roleの権限不足
通常は問題ないのですが、エッジケースで確認できています。
テンプレートから生成されるIAM Role DatadogMetricStreamRole
にlogs:ListTagLogRoup
アクションがないため、リソースのタグ変更があったときに、CloudFormationでエラーが起こります。タグ回りで変更があったりすると引っかかり、ロールバックで解消できないため、テンプレートを書き換えるかスタックを作り直すしか回避策がないので注意です。
また、Issueではs3:PutBucketTagging
とcloudwatch:TagResource
が足りないケースも報告されています。
ちなみにCloudFormation StackはGitHubで公開されているのでOSS開発っぽくなっています。問題を見つけたならここに修正PRを出せばいいのですが、1年近く取り込みが放置されており、Issueも放置気味なのでちょっと出すのを躊躇しています。
テンプレートのメトリクスストリームのInclude/Excludeの設定数上限
コストを抑えるためにNamespaceを絞ることが難しいです。
Metric Streamのコスト対策は「単純に取り込むNamespaceを絞ること」が第一選択肢ですが、CloudFormationのYAML定義はフィルターを3つしか渡せない作りです。3つ以上設定するには、CloudFormation Stackのテンプレートを手元で管理に切り替えて修正する必要があります。幸いテンプレートは公開されているので、頑張るのもいいでしょう。
ParameterのDatadogApiKey
が毎回変更差分と検出
TerraformのバグがPulumiにも影響を及ぼしています。
Pulumiのバグかと思いきやTerraform由来のバグでした。ワークアラウンドとしてIgnoreChanges
するように案内されていますが、IgnoreChangesをこういう用途で使うと「DatadogApiKey
を更新したいときに更新できない状況が起こり、また気づきにくい」です。
問題にならない限りはそれでもいいのですが、忘れたころにやる操作でハマることをが約束されているのはいただけません。困ったものですが、CloudFormation StackをIaCから呼び出すなら運用回避になることを割り切りましょう。
まとめ
Datadogが想定している動作を把握するのは大事なので、CloudFormationから作成してみて動作確認するのはいいことです。ただ、トラブルも確認できているのでCloudFormation定義を丸っとPulumiにポートする記事も別途書きます。
参考
- Amazon Data Firehose を使用した AWS CloudWatch メトリクスストリーム
- DataDog/cloudformation-template | GitHub
- Amazon CloudWatchの費用を半額削減した話 - Studyplus Engineering Blog
- Analyzing, optimizing, and reducing CloudWatch costs - Amazon CloudWatch
- UsageTypeでCloudWatch Serviceを絞り込んでください。GMD-Metrics=Bulk Get Metric Dataを指します。↩