Datadog の AWS 統合機能を使いつつ、メトリクス収集対象のリージョンやリソースタイプをデフォルトから変更してみた

2024.06.03

いわさです。

先日 Datadog で AWS 環境を監視する機会があったので、導入とデフォルトからの変更点をメモしておくことにしました。
Datadog には多くの Integrations が用意されており、AWS も統合が可能です。
しかもポチポチボタンを押すだけで CloudFormation をデプロイしてそのまま監視を開始することが出来ます。

東京リージョンにセットアップしようとしたところエラーが発生したのでその解決方法を調べました。
また、デフォルトだとメトリクスの収集範囲が広くコストが高額になってしまう可能性があったのでスコープをデフォルトよりも小さくしてみることにしました。

AWS 統合導入時のエラー

Datadog に対して AWS を統合する手順は非常に簡単です。
Integrations メニューから Amazon Web Services を選択します。

あとは Datadog 側の API キーを選択するだけで CloudFormation のデプロイ画面に遷移することが出来ます。

ただ、本日時点で私が東京リージョンを対象にデプロイしたところスタックの作成に失敗しました。

Embedded stack arn:aws:cloudformation:ap-northeast-1:123456789012:stack/DatadogIntegration-DatadogAPICall-Q20TJJ4BFBS9/1dc921d0-2147-11ef-859d-0e0a6af253d9 was not successfully created: The following resource(s) failed to create: [DatadogAPICall].

AWS Logs to Datadog オプションを変更したり、API キーを作成し直したりしてみましたがどうもうまく行きません。

エラーが発生したカスタムリソースのログを見てみると "Exception during processing: HTTP Error 403: Forbidden" というメッセージが。
カスタムリソースのコードも覗いてみると、どうやら Datadog 側の API を叩いているのですが、そこで Forbidden が発生している様子。

:

def call_datadog_api(event, method):
    api_key = event['ResourceProperties']['APIKey']
    app_key = event['ResourceProperties']['APPKey']
    api_url = event['ResourceProperties']['ApiURL']
    account_id = event['ResourceProperties']['AccountId']
    role_name = event['ResourceProperties']['RoleName']
    host_tags = event['ResourceProperties']['HostTags']
    cspm = event['ResourceProperties']['CloudSecurityPostureManagement']
    metrics_disabled = event['ResourceProperties']['DisableMetricCollection']

    # Make the url Request
    url = 'https://api.' + api_url + '/api/v1/integration/aws'
    values = {
        'account_id': account_id,
        'role_name': role_name,
    }
    if method != "DELETE":
        values["host_tags"] = host_tags
        values["cspm_resource_collection_enabled"] = cspm == "true"
        values["metrics_collection_enabled"] = metrics_disabled == "false"

    headers = {
        'DD-API-KEY': api_key,
        'DD-APPLICATION-KEY': app_key,
        'Dd-Aws-Api-Call-Source': API_CALL_SOURCE_HEADER_VALUE,
    }
    data = json.dumps(values)
    data = data.encode('utf-8')  # data should be bytes
    request = Request(url, data=data, headers=headers)
    request.add_header('Content-Type', 'application/json; charset=utf-8')
    request.add_header('Content-Length', len(data))
    request.get_method = lambda: method

    # Send the url Request, store external_id
    response = urllib.request.urlopen(request)
    return response

:

APIKey あたりが怪しそうだなと思って Datadog 側のアクセスキーを作り直してみたりしてみたのですが、色々調べていると同じ現象に当たっている方を発見...!

なるほど。どうやらカスタムコード内のapi_urlが誤っているようでした。
Datadog サイトと「サイトパラメーター」をあわせる必要があるそうで、上記参考記事と同様に私も次のようにap1.datadoghq.comを使っていました。

確かにデフォルトだと次のようにdatadoghq.comが選択されていますね...!
これは US1 サイト(https://app.datadoghq.com)の場合に使えるサイトパラメーターでした。

ap1.datadoghq.comを選択したところ無事スタックが作成出来ました。

デフォルト収集メトリクスのスコープを調整する

さて、この Datadog AWS インテグレーション機能を使うと、すぐに AWS 側のメトリクスを提供してくれるようになります。
デフォルトでは CloudWatch API をポーリングするような動きをします。

で、よく話に挙がるのですが大規模に使用していると AWS 側の GetMetricData の料金が高額になってしまう場合があります。
GetMetricData API の料金が高額になる場合は代替の方法として CloudWatch Metric Streams を使うという方式もあり次の記事で紹介されています。

そして Datadog でも CloudWatch Metric Streams はサポートされています。

ただし、一見安くなる可能性を秘めていそうですが、次の Datadog 公式ドキュメントでは逆にコストが高くなる可能性があると言及されています。

AWS は、CloudWatch メトリクスストリームのメトリクスアップデートの数と Amazon Data Firehose に送信されたデータボリュームに基づいて課金します。そのため、ストリーミングしているメトリクスのサブセットの CloudWatch コストが増加する可能性があります。このため、Datadog は、より低いレイテンシーが最も必要な AWS メトリクス、サービス、リージョン、アカウントにメトリクスストリームを使用し、それ以外ではポーリングを使用することをお勧めします。

また、いくつかの外部記事を引用させて頂きますが、CloudWatch Metric Streams に切り替えてみたところ逆に料金が高くなってしまったという情報を見つけることが出来ます。

したがって、公式ドキュメントに従い、タイムラグを抑えたい場合は CloudWatch Metric Streams を採用、それ以外ではデフォルトのポーリング形式のままがコスト的にも良さそうです。

リージョン選択

じゃあデフォルトのポーリング形式でコストを抑えるためにどうしたら良いのか。

まず、ポーリングの間隔はどうやら Datadog サポートへ連絡することで変更の余地がありそうです。
デフォルトは 10 分ですが、短くしたり、あるいは頻度を下げるために長くすることも出来るそうです。

また他の方法として、デフォルトだと全リージョンにポーリングしているのですが必要なリージョンを絞ることは出来そうです。
リソース数によって変動しますが、確かに対して稼働していないリージョンでも一定のポーリングが発生していそうな気配を感じます。(図は CloudWatch の使用量メトリクス。Datadog からのものであるかはわからない)

Integrations の General タブからリージョンを選択することが出来ます。
デフォルトは全リージョンが選択されています。

ここでは試しに大阪リージョン(ap-northeast-3)のみとしてみました。

しばらく経つと先ほどまで東京リージョン(ap-northeast-1)の API 実行数が多かったのですが入れ替わる形となりました。経過観察は必要そうですが、このリージョンスコープを絞るのは悪くなさそうです。

サービス選択

また、メトリクスを収集する対象サービスを絞り込むことも出来ます。
デフォルトではサポートされているほとんどのサービスが有効化されていました。

試しに API Gateway と EC2 だけを有効化してみます。

この環境の大阪リージョンでは EC2 が 8~9 台起動されていたのですが、そのタイミングに大阪リージョンだけ EC2 にあわせて API 取得数が増加していました。これは正直もう少し動かして見ないとなんとも言えないなぁという間隔ではあるのですが対象リソースタイプを絞り込むことで API 取得数が減りそうな雰囲気は感じます。

より厳密に行うのであれば、オプションとしてタグを使ってリソースを絞り込むことも出来るので、さらに API 取得対象を絞り込むことも出来そうです。

さいごに

本日は Datadog の AWS 統合機能を使いつつ、リージョンやリソースタイプをデフォルトから変更してみました。

小規模な環境で少し観察しただけなので、もう少しリソースを追加したり経過観察しないといけないとは思ってます。
取得対象を狭める形なのでデメリットもまぁありますが、スコープを絞ることが出来るのであれば CloudWatch のコスト削減効果は見込めそうです。