以下の内容はhttps://tech.mntsq.co.jp/entry/2025/11/28/151312より取得しました。


AWS / Azure / Google Cloud 各コストを Datadog に集約して確認する

MNTSQ Tech Blog TOP > 記事一覧 > AWS / Azure / Google Cloud 各コストを Datadog に集約して確認する

はじめに

弊社では AWS を主軸としたインフラ構成をもってプロダクトを展開していますが、一部では AWS 以外にも Azure および Google Cloud も活用しています。それぞれの棲み分けは以下のようなものになります。

  • AWS:ほとんど全て
    • コンピュート / ネットワーク / ストレージ / DB / セキュリティ etc.
  • Azure:OCR 関連
  • Google Cloud:LLM を使う処理および OCR 関連

利用規模としては AWS >> Google Cloud > Azure といったものになり、結果としてこれらクラウドベンダーの利用にかかるコスト(利用料金の意。以下本稿では「コスト」を料金を指す意味でのみ用います)割合も AWS が支配的なものになります*1

これらクラウドベンダーを扱う上でネックになることといえば勿論コストです。各ベンダーそれぞれコスト確認のための優れたツールを提供していますが、無論各ツールはそれぞれのベンダー内に閉じるものであり、例えば「今月 Google Cloud コストが普段と比べて妙な増え方をしているが AWS 側でも変動している形跡は無いだろうか?」といった調査をする場合、AWSGoogle Cloud とで行きつ戻りつしながらコスト調査を行う必要が出て来ます。

このあたりへの対処として、弊社では Datadog にコスト情報を集約する という選択肢をとることにしました。この内容について解説します。

構成

概要を以下に示します。

図の複雑さの違いが示すとおり、Datadog にコスト情報を連携させる戦略は各クラウドベンダーによって異なります。やりかたは一通りではないという前置きをしつつ、弊社では以下のような手法をとっています。

  • AWS:consolidated billing アカウントで Cost & Usage Report (CUR) を生成し、Datadog で CUR の内容を収集する
    • AWS Organizations 管理下にある全 AWS アカウントのコスト情報を Datadog に連携する
      • 弊社では例外なく全 AWS アカウントが AWS Organizations 管理下にあるので、個別に連携を頑張るよりも合理的
    • 弊社では AWS Organizations 管理アカウントが consolidated billing アカウントを兼ねており、適切な権限制御をする前提において 管理アカウントと Datadog とを連携するのみで事足りる
  • Azure:コストを追いたいサブスクリプションに対し cost export を設定し、その結果を Datadog で収集する
  • Google Cloud:Datadog 連携用のプロジェクトでコスト情報を BigQuery + Cloud Storage で扱えるようにした上でその内容を Datadog で収集する
    • プロダクト向けのワークロードを稼動させているプロジェクトは同一の請求アカウントに紐付けるような構成としているので、追跡したいコスト*2としてはこの請求アカウントに関するもの
    • Datadog 連携用のプロジェクトもこの請求アカウントに紐付け(後述)、必要なコスト情報を単一プロジェクトに集約する格好とした

さも最初から設計したかのように書いていますが、実際には殆どの要素を Datadog が提供するドキュメントに従ってのものになります。以後本稿でも基本的にはこの情報を前提にします。

なお Azure のみ単一のサブスクリプションを対象としていますが、これは以下背景によります。弊社事情である、というのが要旨です。

  1. 本番ワークロードを処理するサブスクリプションが Azure コストの支配的な要素を占めており、それ以外のサブスクリプションのコストを追う動機が薄い
  2. AWS / Google Cloud とは異なり Azure はプロダクト用途以外にもコーポレート用途の要素があり、SRE で管理できていない部分がある
    • 具体的には管理グループ単位でのコスト監視設定を行うのが難しかった
    • プロダクト向けのワークロードを考える範囲においては 1. の理由で特定のサブスクリプションを追跡できれば充分という背景があった

設定

基本的には前述の Datadog が提供する設定手順に従えばスムーズに設定できます。とくにコスト関連のお膳立てが整っていれば Datadog との連携およびコスト関連の情報取得はかなりスムーズに設定できます。

一方でコスト情報を適切に出力する為の作業で一部難儀したことがありました。これは作業者が AWS の経験に寄り過ぎていることも一因ですが、ひょっとしたら同じようなハマり方をする方がいるかもしれません。恥をしのんで解説します。

なお以下では実際に筆者が作業した過程をなぞるかたちでドキュメントベースで解説しますが、実際には Cloud Cost のアカウント設定画面 からウィザードに従って作業をすすめるほうが直感的だったりします。また文中で示すリンクテキストのリンク先は特記のない限り Datadog 公式ドキュメントです。

AWS

作業対象(前掲概要図から抜粋)

Datadog の公式ドキュメントは こちら になります。やることはおおまかに

  1. Datadog と AWS アカウントとの連携設定
  2. AWS アカウント側での Cost & Usage Report (CUR) の設定
  3. Datadog 連携用 IAM ロールで 2. の CUR が参照できるよう権限の設定
  4. Datadog 側での Cloud Cost 設定

の4点です。

ドキュメントでは CloudFormation を使う方法と手作業 (manual) で進める方法の2択がありますが、弊社では既存設定を Terraform で IaC 化しているためにて本作業も Terraform で進めるべく、手作業での設定としました。この場合に参考にすべき手順は こちら になります。

1.4. は上掲手順に従うのみで大丈夫そうでした。2.3. *3を Terraform で設定する場合のサンプルコードは以下のようになります。

variable "datadog_external_id" {
  type        = string
  description = "External ID provided by Datadog on AWS integration"
  default = ""
}

data "aws_caller_identity" "current" {}

data "aws_iam_policy_document" "datadog_integration" {
  statement {
    actions = [
      "s3:PutObject",
      "s3:GetBucketPolicy",
    ]
    resources = [
      aws_s3_bucket.datadog_integration.arn,
      "${aws_s3_bucket.datadog_integration.arn}/*",
    ]
    principals {
      type = "Service"
      identifiers = [
        "billingreports.amazonaws.com",
        "bcm-data-exports.amazonaws.com",
      ]
    }
    condition {
      test     = "StringLike"
      variable = "aws:SourceArn"
      values = [
        "arn:aws:cur:us-east-1:${data.aws_caller_identity.current.account_id}:definition/*",
        "arn:aws:bcm-data-exports:us-east-1:${data.aws_caller_identity.current.account_id}:export/*",
      ]
    }
    condition {
      test     = "StringLike"
      variable = "aws:SourceAccount"
      values = [
        data.aws_caller_identity.current.account_id,
      ]
    }
  }
}

resource "aws_s3_bucket" "datadog_integration" {
  bucket = "mntsq-master-datadog-integration"
}

resource "aws_s3_bucket_policy" "datadog_integration" {
  bucket = aws_s3_bucket.datadog_integration.id
  policy = data.aws_iam_policy_document.datadog_integration.json
}

/*
  Datadog の Cloud Cost では CUR 2.0 に対応していない
  legacy CUR の場合は以下リソースを使って定義する
 */
resource "aws_cur_report_definition" "datadog_integration" {
  report_name = "datadog-integration"
  time_unit   = "HOURLY"
  format      = "Parquet"
  compression = "Parquet"
  additional_schema_elements = [
    "RESOURCES",
    "SPLIT_COST_ALLOCATION_DATA",
  ]
  s3_bucket = aws_s3_bucket.datadog_integration.bucket
  s3_prefix = "cost_and_usage_report"
  s3_region = aws_s3_bucket.datadog_integration.region
}

data "aws_iam_policy_document" "datadog_aws_integration_assume_role" {
  statement {
    actions = ["sts:AssumeRole"]

    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::464622532012:root"] # See: https://docs.datadoghq.com/integrations/guide/aws-manual-setup/?tab=roledelegation
    }

    condition {
      test     = "StringEquals"
      variable = "sts:ExternalId"
      values = [
        var.datadog_external_id,
      ]
    }
  }
}

data "aws_iam_policy_document" "datadog_aws_integration" {
  statement {
    actions = [
      /*
      Datadog と AWS との連携 (integration) で何を連携するか(= Datadog にどのような AWS の情報を流すか)によって変わる
      必要に応じて定義する。今回は詳細省略
       */
    ]
    effect    = "Allow"
    resources = ["*"]
  }
}

data "aws_iam_policy_document" "cost_and_usage_report_export" {
  statement {
    effect = "Allow"
    actions = [
      "s3:ListBucket"
    ]
    resources = [
      aws_s3_bucket.datadog_integration.arn,
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "s3:GetObject"
    ]
    resources = [
      "${aws_s3_bucket.datadog_integration.arn}/cost_and_usage_report/*",
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "ce:Get*"
    ]
    resources = [
      "*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "cur:DescribeReportDefinitions"
    ]
    resources = [
      "*"
    ]
  }
  statement {
    sid    = "DDCloudCostListOrganizations"
    effect = "Allow"
    actions = [
      "organizations:Describe*",
      "organizations:List*"
    ]
    resources = [
      "*"
    ]
  }
}

resource "aws_iam_policy" "datadog_aws_integration" {
  name        = "DatadogAWSIntegrationPolicy"
  description = "Allow actions for Datadog Integration"
  policy      = data.aws_iam_policy_document.datadog_aws_integration.json
}

resource "aws_iam_policy" "datadog_cost_and_usage_report_export" {
  name        = "DatadogCurExportPolicy"
  description = "Allow actions required to export Cost and Usage Report to Datadog"
  policy      = data.aws_iam_policy_document.cost_and_usage_report_export.json
}

resource "aws_iam_role" "datadog_aws_integration" {
  name               = "DatadogAWSIntegrationRole"
  description        = "Role to integrate AWS and Datadog"
  assume_role_policy = data.aws_iam_policy_document.datadog_aws_integration_assume_role.json
}

resource "aws_iam_role_policy_attachment" "datadog_aws_integration" {
  role       = aws_iam_role.datadog_aws_integration.name
  policy_arn = aws_iam_policy.datadog_aws_integration.arn
}

# AWS マネージドポリシ。Datadog が Resource Collection 時に要求する
data "aws_iam_policy" "security_audit" {
  name = "SecurityAudit"
}

resource "aws_iam_role_policy_attachment" "datadog_aws_integration_security_audit" {
  role       = aws_iam_role.datadog_aws_integration.name
  policy_arn = data.aws_iam_policy.security_audit.arn
}

resource "aws_iam_role_policy_attachment" "datadog_aws_integration_cost_and_usage_report" {
  role       = aws_iam_role.datadog_aws_integration.name
  policy_arn = aws_iam_policy.datadog_cost_and_usage_report_export.arn
}

Azure

作業対象(前掲概要図から抜粋)

Datadog の公式ドキュメントは こちら になります。やることはおおまかに

  1. Datadog と Azure サブスクリプションとの連携設定
  2. Azure サブスクリプションでの cost export 設定
  3. cost export 結果を収容する storage container を Datadog 連携用 の app registration が参照できるよう設定
  4. Datadog 側での Cloud Cost 設定

の4点です。

Azure については IaC 管理できていない範囲*4につき、手作業で設定をすすめてゆく必要がありました。なお本対応をおこなうまで Azure と Datadog とを組み合わせて利用するケースは弊社内において存在せず、その段階からの作業が必要となった点、補記しておきます。

1. については 手順 を通読することになります。弊社では "Quickstart (recommended)" によって作業をすすめました。

続く 2. ですが、手順 に従い作業をする前に

  • storage account
  • blob container

を用意しておく必要があります。Datadog と連携した Azure サブスクリプション内に storage account を作り、その中に blob container を設ける格好です。cost export の結果は最終的に blob container 内に格納されます。上述二点が用意できたら前掲手順に従い cost export を設定します。いくつかフォーマットを設定できますが、弊社では AWS の CUR に合わせて Parquet を選定しました。

3. については 手順 に従い素直に設定すれば大丈夫です。Azure の世界観ではタブは 画面左側 にあるので、手順内で "tab" と説明されるものは画面左側にありますので注意が必要です*5

4. については手順通りで割合簡単に設定が可能なので詳細は省略します。

Google Cloud

作業対象(前掲概要図から抜粋)

Datadog の公式ドキュメントは こちら です。以下5点が必要な作業となりました。本対応をおこなうまで Google Cloud と Datadog とを組み合わせて利用するケースは弊社内において存在せず、その段階からの作業が必要となった点、補記しておきます。

  1. Datadog 連携用のプロジェクトを用意し、Datadog との連携設定を実施
  2. cost export 設定を対象プロジェクト内の BigQuery から取り扱う設定を追加
  3. 用意したプロジェクトに対し請求アカウントからの cost export 設定を追加
  4. BigQuery 出力先となる Cloud Storage バケットを対象プロジェクト内に追加
  5. Datadog 用 service account から 4. で設定した Cloud Storage バケットが参照できるよう権限を設定
  6. Datadog 側での Cloud Cost 設定

Google Cloud についても IaC 管理できていない範囲*6につき、手作業で設定をおこないます。

1. については 手順 を通読し必要な作業を行います。どのように Google Cloud プロジェクトを設計するかは個々のケースによって様々な方法論があると思いますが、弊社では素直に Datadog と連携するためのプロジェクトを新設する方向にしました。この際プロジェクトは適当な請求アカウントに紐付けないと Datadog との連携設定でエラーになるため、事前に請求アカウント向けの設定を Google Cloud 側の手順 などを参照して済ませておく必要があります。

2. については こちら が手順となりますが、ここでは既に BigQuery データセットが存在していることが前提になります。利用するプロジェクト内で事前に用意しておき、その上で 3. に臨みます。cost export 設定を 請求アカウントから 実施する必要があります。

4.5.手順 に従い素直に作業します。ここで手順内の "co-located" は BigQuery データセットと Cloud Storage バケットとでリージョン設定を同一にせよという意味になる*7ので、そのように設定します。

6. においては手順に従えば作業は簡単にできます。以下が必要になるので適宜参照できるよう準備して設定に臨みます。

なお BigQuery でコスト情報が取り扱えるようになる前に Cloud Cost 設定に臨むとエラーになります。おおむね数時間程度*8待つと BigQuery でコスト情報が取り扱えるようになるので、それ以降で設定を試みるとよいでしょう。

結果

全ての設定が済むと Cloud Cost 概要画面 で設定したクラウドベンダー横断の状況が観察できるようになります。backfill 的な作業をしない限りは基本的に Cloud Cost 利用開始時点のコスト情報が連携されるので、これが真価を発揮するのは充分にコスト情報が蓄積されてからとなるでしょう。

Cloud Cost そのものの機能を使いこなすには弊社としてもまだ至っていません。有効にしてから日が浅く、まだ充分なデータが溜まっていないという側面があります。 一方で Datadog メトリックとして各クラウドベンダのコスト情報を適切な分解能でもって Datadog 内で扱える というメリットは Cloud Cost そのものの機能を差っ引いても享受でき、弊社ではひとまず

  1. AWS / Azure / Google Cloud 全体のコスト確認用
  2. 上記のうち主要なコストファクターとして扱われるアカウント / プロジェクトに絞ったコスト確認用
  3. プロダクト環境単位でアカウント / プロジェクト / サブスクリプションを整理した上で「環境」を横断してのコスト確認用

といった区分でダッシュボードをつくり、定期的に傾向をみる、といった運用をとっています。 3. が少々解り辛いのですが、要するに本番環境として扱われるお客様のワークロードを実際に捌いている AWS アカウント / Google Cloud プロジェクト / Azure サブスクリプションのコストを俯瞰して観察するというものです。

おわりに

Datadog の Cloud Cost を使用し、社内で利用している各クラウドベンダーのコストを集約して観察する方法について取り扱いました。費用変動の痕跡をつぶさに追う上で参照すべき情報が散逸している状況は多くの苦労を伴いますが、ひとつの場所を確認しておけば間に合う、という状況は中々の心理的安全性が見込めます。Cloud Cost は SaaS コストや Datadog 自身のコストも対象に含めることが出来る*9ので、さらなる観測範囲の拡張をおこない精度の高いコスト監視体制を組むことも可能そうです。弊社でも Cloud Cost の利用は開始したばかりといった状況なので、まずはデータの蓄積をしつつ、よりよい使い所を検討できればと考えています。

マルチクラウド構成におけるコスト監視に課題感をお持ちの方の対応検討の一助になれば幸いです。

MNTSQ 株式会社 SRE 秋本

*1:詳細な数字は割愛しますが AWS の利用コストは Google Cloud / Azure に比べ桁が1つ異なります

*2:もちろん「プロダクト向けのワークロード」を稼動させているプロジェクトが対象です。というのも弊社ではこれ以外にもプロジェクトが様々な用途で存在し、それらプロジェクトは別の請求アカウントに紐付きます。これら全てのコスト情報を集約させると話が大きくなってしまうので、今回はワークロード稼動環境に絞るものとしました

*3:IAM ロール / ポリシ関連のコードがあることから推測できるとおり、実際には 1. に対応する範囲も含んでいます

*4:Terraform でやりたい

*5:本稿筆者はこれでけっこうハマりました。実は CUI が主な生活空間なので、GUI 操作には苦手意識があります

*6:Terraform でやりたい2

*7:恥ずかしながらドキュメントから誘導される https://docs.cloud.google.com/bigquery/docs/exporting-data#data-locations を読んでも勝手が解らず少々ハマりました。英語的なニュアンスが汲み取れればよかったのですが……

*8:だいたい Google Cloud 側で設定完了してから 4 -- 5 時間といったところでした。状況による変動がかなりあると推測されるので、ひとつの参考事例とご理解ください

*9:https://docs.datadoghq.com/cloud_cost_management/




以上の内容はhttps://tech.mntsq.co.jp/entry/2025/11/28/151312より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14