TerraformからDatadogを操作するには、Datadog社が公開している公式プロバイダー DataDog/datadog を使います。2026年9月24日公開のv4.22.0が最新で、2026年3月のv4.0.0からTerraform 1.1.5以上が必須になりました。この記事では、providerブロックと認証の渡し方、日本リージョン(AP1)で必要な設定、モニターとダッシュボードのコード化、既存設定の取り込み、AWSインテグレーションの構築までを順に説明します。載せたHCLは抜粋ですが、変数宣言や読み込むJSONファイル、AWSプロバイダーの設定を補った構成で、Terraform 1.16.4とプロバイダー4.22.0(AWSは6.66.0)の terraform validate を通しています。
まとめ
- プロバイダーは
source = "DataDog/datadog"。v4系はTerraform 1.1.5以上が必要で、v3系のまま使い続けるならversion = "~> 3.0"で固定します。 - APIキーとアプリケーションキーはコードに書かず、環境変数
DD_API_KEYとDD_APP_KEYで渡します。 - 日本のAP1サイトを使っているなら、
api_url = "https://api.ap1.datadoghq.com/"か環境変数DD_HOSTで接続先を指定します。どちらも無いとUS1へ接続します。 - 既存のモニターやダッシュボードは、importブロックか監視画面の「Export to Terraform」でコードへ取り込みます。Terraformerはリポジトリがアーカイブ済みです。
- AWS連携は
datadog_integration_aws_account1本で書きます。旧datadog_integration_awsはv4.0.0で削除されました。IAMロールの信頼先アカウントはDatadogのサイトごとに違い、AP1は417141415827です。
DatadogとTerraformの役割の違い
「datadog vs terraform」で検索されることがありますが、両者は競合する製品ではありません。Datadogはメトリクス・ログ・トレースを集めて監視するSaaSで、Terraformはクラウドやサービスの設定をコード(HCL)で宣言して作成・変更するIaCツールです。Terraformはプロバイダーという単位で操作対象を増やす仕組みを持ち、Datadog用のプロバイダーを入れると、監視SaaSであるDatadogの設定そのものをAWSのリソースと同じ流れで管理できます。
Terraformで扱うのは「Datadogの設定」であって、監視データそのものではありません。モニター、ダッシュボード、SLO、ログのインデックスやパイプライン、ユーザーやロール、AWSなどのクラウド連携が対象で、v4.22.0のドキュメントにはリソースが167種類載っています。ホストへのAgent導入はDatadogプロバイダーの対象外で、TerraformでやるならAWSプロバイダーでEC2を作る際の user_data などで別に書きます。Datadog自体の機能構成はDatadogとは何か?機能やメリット、導入の背景を詳しく解説で整理しています。
Datadog Providerの導入とproviderブロックの書き方
required_providersによるv4系の固定
公式ドキュメントの例は source だけを書いてバージョンを指定していませんが、実運用では固定しておくべきです。Datadogのプロバイダーは2026年7月29日の4.17.0から9月24日の4.22.0までの約2か月で、マイナー版が5回出ています。
terraform {
required_version = ">= 1.1.5"
required_providers {
datadog = {
source = "DataDog/datadog"
version = "~> 4.22"
}
}
}
provider "datadog" {
api_url = "https://api.ap1.datadoghq.com/"
# api_key と app_key は環境変数 DD_API_KEY / DD_APP_KEY から読ませる
}
~> 4.22 は4.22以上5.0未満を許す指定です。terraform init で実際に選ばれた版は .terraform.lock.hcl に記録されるので、このファイルもリポジトリに含めます。制約の書き方とlockファイルの扱いはterraform providerのバージョン制約とalias設計|lockファイルの運用判断で詳しく扱っています。
v3系から上げる場合、v4.0.0の破壊的変更は6件です。影響が大きいのは3つで、Terraform本体の最低版が1.1.5になったこと、旧AWSインテグレーション系の4リソースが削除されたこと、datadog_monitor の locked 属性が削除されたことです。
環境変数によるAPIキーとアプリケーションキーの受け渡し
キーで認証する標準の方式では、APIキーとアプリケーションキーの2本を使います(後述のBearerトークン方式は別)。どちらもproviderブロックに直接書けますが、変数経由でも terraform.tfvars に残りやすいため、環境変数で渡すのが安全です。
export DD_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
export DD_APP_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
terraform plan
v4.22.0のソースでは、値を探す順番が決まっています。providerブロックに書いた値が最優先で、空なら DD_API_KEY、それも無ければ DATADOG_API_KEY を読みます(アプリケーションキーとURLも同じ順です)。CIで両方の名前が設定されていると、DD_ 側だけが使われます。
キーが1本も渡っていない状態で terraform plan を実行すると、次のエラーで止まります(Terraform 1.16.4とプロバイダー4.22.0で実測)。
Error: api_key and app_key, bearer_token, or orgUUID must be set unless validate = false
エラー文にある bearer_token は、個人アクセストークン(ddpat_ 始まり)とサービスアカウントのアクセストークン(ddsat_ 始まり)を受け付ける引数です。キーの代わりにAWSの認証情報で入る cloud_provider_type = "aws" も用意されていますが、こちらはPreviewで、サポートに申請して有効化してもらう必要があります。アプリケーションキーに付けるスコープの絞り方はDatadog APIの実装手順|2種類のキーの権限分離とモニター操作・429対策を参照してください。
日本のAP1サイトで必要なapi_url
Datadogはサイトごとにデータが完全に分かれており、api_url の既定値は米国のUS1(https://api.datadoghq.com)です。日本にデータを置くAP1で契約している組織が指定を忘れると、キーが正しくてもUS1側で認証が通らず失敗します。ログイン画面のURLで自分のサイトを確認し、次の値を入れます。
| サイト | 所在地 | api_url |
|---|---|---|
| US1 | 米国 | https://api.datadoghq.com/ |
| US3 | 米国 | https://api.us3.datadoghq.com/ |
| US5 | 米国 | https://api.us5.datadoghq.com/ |
| EU1 | ドイツ | https://api.datadoghq.eu/ |
| AP1 | 日本 | https://api.ap1.datadoghq.com/ |
| AP2 | オーストラリア | https://api.ap2.datadoghq.com/ |
URLの末尾に /api/ を付けると誤りです(プロバイダーのドキュメントに明記)。環境変数で渡すなら DD_HOST を使います。
HCLによるモニターとダッシュボードの定義
datadog_monitorの最小構成
モニターは name・type・query・message の4つが必須です。次は、ユーザー空間のCPU使用率(system.cpu.user)の直近5分平均をホスト単位で評価するメトリクスモニターの例です。
variable "env" {
type = string
default = "prod"
}
resource "datadog_monitor" "cpu_high" {
name = "[${var.env}] CPU使用率が高いホスト"
type = "metric alert"
query = "avg(last_5m):avg:system.cpu.user{env:${var.env}} by {host} > 90"
message = <<-EOT
{{host.name}} のCPU使用率が {{value}}% に達しました。
@slack-ops-alerts
EOT
monitor_thresholds {
warning = 80
critical = 90
}
notify_no_data = true
no_data_timeframe = 10
renotify_interval = 60
tags = ["env:${var.env}", "team:platform", "managed-by:terraform"]
}
書くときに引っかかりやすい点が3つあります。1つ目は query の書式で、スキーマの説明に「UIで見えるクエリとは同じではない」とあり、書式はAPIリファレンスのモニター作成の項に従います。query の末尾に書いたしきい値(ここでは90)は、monitor_thresholds の critical と揃えます。2つ目は検証のタイミングで、terraform plan の時点でプロバイダーがクエリの中身を検証します(datadog_monitor リソース内で validate = false を指定すると省略)。3つ目は type で、作成後は変更できません。モニタータイプの選び方やしきい値の決め方はDatadogモニターのタイプ選定と閾値設計:評価ウィンドウと通知テンプレートの実装手順で扱っています。
ダッシュボードをdatadog_dashboard_jsonで持つ判断
ダッシュボード用のリソースには、ウィジェットをHCLのブロックで1つずつ書く datadog_dashboard と、JSONをそのまま渡す datadog_dashboard_json があります。既存のダッシュボードをコード化するなら後者が現実的です。画面右上の設定アイコンにある「Export dashboard JSON」で書き出したファイルを、次の例では dashboards/service_overview.json として保存して読み込みます。
resource "datadog_dashboard_json" "service_overview" {
dashboard = file("${path.module}/dashboards/service_overview.json")
}
ウィジェットが数十個あるダッシュボードをHCLに書き直すと、差分レビューがかえって読みにくくなります。UIで作って書き出し、Terraformは適用と履歴管理だけを担う、という分担が保守しやすい形です。ウィジェットの選び方はDatadogダッシュボードの作り方|ウィジェット選定とテンプレート変数の設計手順を参照してください。
datadog_restriction_policyによる編集権限の管理
v4.0.0で datadog_monitor の locked 属性が削除され、モニターの編集権限は datadog_restriction_policy で付ける方式が推奨になりました。restricted_roles は今も使えますが、アップグレードガイドは移行を強く推奨しています。更新時に一度だけ restricted_roles = (known after apply) の差分が出ることもガイドに書かれています。
resource "datadog_restriction_policy" "cpu_high" {
resource_id = "monitor:${datadog_monitor.cpu_high.id}"
bindings {
principals = ["role:00000000-0000-0000-0000-000000000000"] # 実在するDatadogロールのUUIDに置換
relation = "editor"
}
}
既存のDatadog設定をTerraformへ取り込む手順
importブロックとgenerate-config-out
Terraform 1.5以降では、importブロックに取り込み先とIDを書いて plan で確認できます。IDの形式はリソースごとに違い、モニターは数値(公式例は 2081)、ダッシュボードは sv7-gyh-kas のような3区切りの文字列です。どちらもブラウザで開いたときのURLに含まれています。
import {
to = datadog_monitor.legacy_disk
id = "1234567"
}
terraform plan -generate-config-out=generated.tf
-generate-config-out を付けると、Terraformが既存の設定を読んでresourceブロックを書き出します。HashiCorpのドキュメントでは今も実験的機能の扱いで、生成形式は今後のマイナー版で変わりうると書かれています。生成結果は下書きとして読み直し、整えたあとの plan で取り込み以外の追加・変更・削除がないことを確認します。その後 terraform apply でstateへの取り込みを確定し、再度 plan で変更がないことを確かめます。importブロックとCLIの terraform import の使い分けはterraform importで既存リソースをコード化する手順|importブロックとCLIの使い分けにまとめています。
UIのExport to TerraformとTerraformerの現状
モニターが数百あるなら、Datadogの画面側の書き出し機能を先に使います。Monitor Listで対象を選び、一括操作メニューの「Export to Terraform」を押すと、選んだモニターのTerraform定義が生成されます。Syntheticsのテスト(APIテスト、Multistep APIテスト、ブラウザテスト)にも同じ書き出し機能があり、datadog_synthetics_test のブロックがクリップボードにコピーされます。
一括取り込みの定番だったTerraformer(GoogleCloudPlatform/terraformer)は、GitHubのリポジトリがアーカイブされて読み取り専用になっています。最後のリリースは2025年3月26日の0.8.30で、v4系プロバイダーの追従は期待できません。これから移行する場合は、画面の書き出し機能とimportブロックの組み合わせを選んでください。
datadog_integration_aws_accountによるAWSインテグレーション設定
必須ブロックと空ブロックが持つ意味
datadog_integration_aws_account は、AWSアカウント1つとの連携を1リソースで表します。aws_account_id と aws_partition のほか、auth_config・aws_regions・logs_config・metrics_config・resources_config・traces_config の6ブロックがすべて必須です。auth_config には認証方式(IAMロールならロール名)を必ず書き、logs_config・metrics_config・traces_config にはそれぞれ子ブロック lambda_forwarder・namespace_filters・xray_services が要ります。それ以外で中身を空にしたブロックは、Datadog側の既定値を使うという意味になります。
resource "datadog_integration_aws_account" "main" {
aws_account_id = "123456789012"
aws_partition = "aws"
account_tags = ["env:prod"]
aws_regions {
include_only = ["ap-northeast-1", "us-east-1"]
}
auth_config {
aws_auth_config_role {
role_name = "DatadogIntegrationRole"
}
}
logs_config {
lambda_forwarder {}
}
metrics_config {
namespace_filters {}
}
resources_config {}
traces_config {
xray_services {}
}
}
既定値には費用に効くものが含まれます。namespace_filters を空にすると AWS/SQS・AWS/ElasticMapReduce・AWS/Usage の3つが収集対象から外れます。CloudWatchの GetMetricData 呼び出しにかかるAWS側の費用を抑えるためで、SQSのキュー滞留を監視したいなら exclude_only を自分で書き、この除外を解く必要があります。aws_regions を空にすると全リージョンが対象になるため、使っているリージョンが限られるなら include_only で絞ります。Datadog側の課金単位と絞り込みの効き方はDatadog運用のベストプラクティス:タグ設計・監視対象の絞り込み・アラート・コスト抑制で扱っています。
サイトごとに異なるIAMロールの信頼先アカウント
連携用のIAMロールには、Datadog側のAWSアカウントからの sts:AssumeRole を許す信頼ポリシーが要ります。このアカウントIDはDatadogのサイトによって違います。公式ガイドの最初のサンプルに載っている 464622532012 は、US1・US3・US5・EU1用の値です。AP1で同じ値を使うと、ロールを引き受けられず連携が成立しません。
| Datadogサイト | 信頼するAWSアカウント |
|---|---|
| US1・US3・US5・EU1 | 464622532012 |
| AP1(日本) | 417141415827 |
| AP2(オーストラリア) | 412381753143 |
| UK1 | 117348461845 |
data "aws_iam_policy_document" "datadog_assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "AWS"
identifiers = ["arn:aws:iam::417141415827:root"] # AP1の場合
}
condition {
test = "StringEquals"
variable = "sts:ExternalId"
values = [datadog_integration_aws_account.main.auth_config.aws_auth_config_role.external_id]
}
}
}
resource "aws_iam_role" "datadog" {
name = "DatadogIntegrationRole"
assume_role_policy = data.aws_iam_policy_document.datadog_assume_role.json
}
resource "aws_iam_role_policy_attachment" "security_audit" {
role = aws_iam_role.datadog.name
policy_arn = "arn:aws:iam::aws:policy/SecurityAudit"
}
external_id を省略するとDatadogが生成し、その値を信頼ポリシーの条件に参照させます。ロール名は文字列で渡しているので、2つのリソースが互いを参照し合う循環は起きません。上の例はAWSの管理ポリシー SecurityAudit だけを付けていますが、実際に使うときはDatadogが必要とする権限の一覧もロールに付けます。一覧はデータソース datadog_integration_aws_iam_permissions で取得できます。Datadogの公式ガイドThe AWS Integration with Terraformは、この一覧を管理ポリシーの上限6,144文字に収まるよう分割して複数のポリシーに割り当てるHCLを載せているので、それを土台にしてください。
v3系の旧AWSリソースからの移行
datadog_integration_aws・datadog_integration_aws_tag_filter・datadog_integration_aws_log_collection・datadog_integration_aws_lambda_arn の4つは、v3.50.0で後継の datadog_integration_aws_account に置き換えられ、v4.0.0で削除されました。旧リソースを残したままv4へ上げると、そのリソース型はプロバイダーに存在しません。移行はv3系のうちに次の順で済ませます。
- 一覧取得API(List all AWS integrations)をAWSアカウントIDで引き、連携設定のIDを確認します。
- そのIDで
datadog_integration_aws_accountにimportします。 - 取り込みを確認したら、旧リソース4種を
terraform state rmでstateから外します。 - HCLから旧リソースを消し、プロバイダーをv4系へ上げます。
運用で詰まりやすい箇所と対処
大量更新で出るHTTP 429
DatadogのAPIはエンドポイントごとにレート制限があり、超えるとHTTP 429が返ります。プロバイダーには429と5xxで自動的に再試行する仕組みが既定で入っていて、最大3回・タイムアウト60秒・待ち時間の指数の底2で動きます。モニターを数百件まとめて適用すると、この既定では足りないことがあります。
provider "datadog" {
api_url = "https://api.ap1.datadoghq.com/"
http_client_retry_max_retries = 5
http_client_retry_timeout = 120
}
再試行の回数を増やしても429が続くなら、terraform apply -parallelism=5 のように同時実行数(既定10)を下げます。どの制限に当たったかは、レスポンスヘッダーの X-RateLimit-Name と X-RateLimit-Reset で確認できます。
UIでの手修正によるドリフト
Terraformで作ったモニターをUIで直すと、次の plan で差分として出て、apply で元に戻ります。運用担当がUIで付けるタグまで戻したくない場合は、ignore_tag_keys で対象のタグキーを差分の対象から外せます。4.22.0時点で対応しているのはモニターとSLOで、providerブロックに書く全体設定はExperimental扱いです。Terraform管理のモニターに managed-by:terraform のようなタグを付けておくと、UIの一覧で「ここは直さない」と判別できます。
External IDの48時間失効
External IDだけを先に作る datadog_integration_aws_external_id リソースもあります。作成後48時間以内にAWS連携の作成に使わないと失効する点に注意してください。terraform destroy してもstateから消えるだけで、DatadogとAWSの側では何も無効化されません。作り直すときは terraform apply -replace="datadog_integration_aws_external_id.foo" で再生成します。
Terraform管理に向く設定と向かない設定
Datadogの設定をすべてTerraformへ寄せる必要はありません。コード化が効くのは、本番環境のモニター、SLO、AWS連携、ロールと権限のように「変更にレビューが要り、環境ごとに同じ形で複製したいもの」です。モジュールにして環境名だけ変えれば、開発・ステージング・本番で同じ監視を揃えられます。モジュールの切り方はTerraform moduleの分割粒度とoutput設計|自作とRegistryの判断が参考になります。
逆に、障害調査のために一時的に作るダッシュボードや、しきい値を試行錯誤している最中のモニターはUIで扱うべきです。作るたびにプルリクエストを必須にすると、急ぎの修正がUIだけで済まされてコードに戻らず、「UIでの手修正によるドリフト」で説明した差分が繰り返し出ます。UIで形が固まってから書き出し、Terraformへ移す順番にすれば、両方の利点を取れます。チームでの適用を1か所に集める場合はHCP Terraformとは?旧Terraform Cloudの料金・無料枠とCLI接続の手順、GitHub Actionsから適用する構成はGitHub ActionsとTerraformでAWSのCI/CDを構築する手順(OIDC・S3ネイティブロック対応)を参照してください。
よくある質問
Datadog Terraform Providerのsourceは何を書けばよいですか?
source = "DataDog/datadog" です。Terraform Registry上の正式名は DataDog/datadog で、ソースコードはGitHubの DataDog/terraform-provider-datadog にあります。2026年9月時点の最新は4.22.0で、Terraform 1.1.5以上が必要です。
TerraformでDatadogのAPIキーをコードに書かずに渡すには?
環境変数 DD_API_KEY と DD_APP_KEY を設定して、providerブロックの api_key と app_key を省略します。HCP Terraformで実行する場合は、ワークスペースの環境変数にsensitive指定で登録します。
SLOやダウンタイムもTerraformで管理できますか?
できます。SLOは datadog_service_level_objective、ダウンタイムは datadog_downtime_schedule を使います。旧来の datadog_downtime はドキュメント上で非推奨とされ、後継として datadog_downtime_schedule が指定されています。
datadog_integration_awsを書くとエラーになるのはなぜですか?
プロバイダーv4.0.0(2026年3月4日)で削除されたためです。後継の datadog_integration_aws_account に書き換えます。stateに旧リソースが残っている場合は、v3系のうちにimportと terraform state rm で移行してからv4へ上げます。
TerraformでDatadogを操作した履歴を残す方法はありますか?
コードの変更履歴はGitに残るので、実行の記録を残したい場合はDatadog公式のPythonライブラリに含まれる dogwrap が使えます。dogwrap -n "terraform apply" -k $DD_API_KEY --submit_mode all --tags="source:terraform" "terraform apply -no-color" のようにコマンドを包むと、実行結果がDatadogのイベントとして送られます。