【保存版】TerraformでDatadog環境を構築する完全ガイド2024 – 設定例20個付き

TerraformでDatadog環境を構築するメリット

Infrastructure as Codeで実現する監視設定の自動化

Datadogの監視設定をTerraformで管理することで、以下の自動化メリットが得られます:

  • 環境の一貫性確保
  • 開発・ステージング・本番環境で同一の監視設定を容易に展開
  • 設定の不整合によるインシデントを防止
  • terraform workspaceによる環境別の設定値管理
  • 迅速なセットアップ
  # モニター設定の例
  resource "datadog_monitor" "cpu_usage" {
    name    = "High CPU Usage Alert"
    type    = "metric alert"
    message = "CPU usage is too high"

    query = "avg(last_5m):avg:system.cpu.user{environment:production} by {host} > 90"

    monitor_thresholds {
      critical = 90
      warning  = 80
    }
  }

コードレビューで実現する監視品質の向上

Terraformコードによる監視設定のバージョン管理により:

  • GitHubなどでのPRベースのレビュー実施
  • 設定変更の意図や背景の明確化
  • チーム全体での知見共有と品質向上
  • 設定ミスの早期発見

例:レビュー時の確認ポイント

# SLOの定義例
resource "datadog_service_level_objective" "http_requests" {
  name        = "HTTP Requests Success Rate"
  type        = "metric"
  description = "SLO tracking success rate of HTTP requests"

  thresholds {
    timeframe = "7d"
    target    = 99.9
    warning   = 99.95
  }

  query {
    numerator   = "sum:http.requests.success{*}"
    denominator = "sum:http.requests.total{*}"
  }
}

バージョン管理による設定変更の追跡とrollback

Gitでの変更履歴管理により:

  • 設定変更の追跡可能性確保
  • 問題発生時の原因特定が容易
  • terraform planによる変更影響の事前確認
  • 必要に応じた設定の巻き戻し

変更管理のベストプラクティス:

  1. ブランチ運用による変更の分離
  2. terraform planの結果をPRにコメント
  3. 承認フローと連携した適用管理
  4. 変更履歴の文書化

Terraform Datadog Providerの基本設定

API キーと Application キーの取得方法

Datadogとの連携に必要なキーは以下の手順で取得できます:

  1. API キーの取得
  • Datadogコンソールの[Organization Settings] > [API Keys]に移動
  • [New Key]をクリックして新規API キーを作成
  • キーの用途に応じて適切な名前を設定(例:terraform-integration
  1. Application キーの取得
  • [Organization Settings] > [Application Keys]に移動
  • [New Key]から新規Application キーを作成
  • 必要最小限の権限を付与

セキュリティのベストプラクティス:

  • キーは環境変数として管理
  • GitHubなどにキーを直接コミットしない
  • 定期的なキーのローテーション実施

provider ブロックの設定例と解説

基本的なprovider設定:

# プロバイダーの要件定義
terraform {
  required_providers {
    datadog = {
      source  = "DataDog/datadog"
      version = "~> 3.30.0"  # 最新の安定バージョンを指定
    }
  }
}

# プロバイダーの設定
provider "datadog" {
  api_key = var.datadog_api_key
  app_key = var.datadog_app_key
  api_url = "https://api.datadoghq.com/"  # リージョンに応じて変更
}

# 変数定義
variable "datadog_api_key" {
  type        = string
  description = "Datadog API Key"
  sensitive   = true  # 機密情報としてマーク
}

variable "datadog_app_key" {
  type        = string
  description = "Datadog Application Key"
  sensitive   = true
}

基本的なリソース定義の書き方

  1. モニターの基本定義
resource "datadog_monitor" "basic_monitor" {
  name    = "Basic System Monitor"
  type    = "metric alert"
  message = "Memory usage is high on {{host.name}}\n@slack-alerts"

  query = "avg(last_5m):avg:system.mem.used{environment:production} by {host} > 85"

  monitor_thresholds {
    critical = 85
    warning  = 75
  }

  notify_no_data    = true
  evaluation_delay  = 300
  include_tags      = true

  tags = ["env:production", "team:infrastructure"]
}
  1. ダッシュボードの基本定義
resource "datadog_dashboard" "basic_dashboard" {
  title       = "System Overview"
  layout_type = "ordered"

  widget {
    timeseries_definition {
      title = "CPU Usage"
      request {
        q            = "avg:system.cpu.user{*} by {host}"
        display_type = "line"
      }
    }
  }
}
  1. タグの付与規則
# グローバルタグの定義例
resource "datadog_monitor" "tagged_monitor" {
  # ... 基本設定 ...

  tags = concat(
    var.global_tags,
    [
      "service:${var.service_name}",
      "env:${var.environment}",
      "managed-by:terraform"
    ]
  )
}

実装のポイント:

  • リソース名は明確で一貫性のある命名規則を使用
  • 必要な属性は全て明示的に指定
  • デフォルト値に依存しない
  • 変数化して再利用可能な設計に

実践的なDatadogリソース定義 – 20個の実例付き

モニターの定義と閾値設定のベストプラクティス

  1. マルチアラート CPU モニター
resource "datadog_monitor" "cpu_high" {
  name    = "[${var.env}] High CPU Usage"
  type    = "metric alert"
  message = <<-EOT
    CPU usage is high on {{host.name}}
    Usage: {{value}}%

    Actions:
    1. Check system load
    2. Review running processes
    3. Scale if necessary

    @team-sre@company.com
  EOT

  query = "avg(last_5m):avg:system.cpu.user{environment:${var.env}} by {host} > 85"

  monitor_thresholds {
    critical          = 85
    warning           = 75
    critical_recovery = 80
    warning_recovery  = 70
  }

  evaluation_delay = 300
  new_host_delay  = 300
  notify_audit    = true
  timeout_h       = 0
  include_tags    = true

  tags = ["team:sre", "criticality:high"]
}
  1. メモリリーク検知モニター
resource "datadog_monitor" "memory_leak" {
  name    = "Memory Leak Detection"
  type    = "metric alert"
  query   = "avg(last_30m):derivative(avg:system.mem.used{environment:prod} by {host}) > 0.1"
  message = "Potential memory leak detected on {{host.name}}"
}
  1. ディスク使用量予測モニター
resource "datadog_monitor" "disk_prediction" {
  name  = "Disk Usage Prediction"
  type  = "metric alert"
  query = "forecast(avg:system.disk.in_use{*}, 'linear', 24, interval='60m', history='1w') > 90"
}

ダッシュボード作成の自動化テクニック

  1. システム概要ダッシュボード
resource "datadog_dashboard" "system_overview" {
  title       = "System Overview"
  layout_type = "ordered"

  widget {
    group_definition {
      title = "System Metrics"

      widget {
        timeseries_definition {
          title = "CPU Usage"
          request {
            q = "avg:system.cpu.user{*} by {host}"
            display_type = "line"
          }
        }
      }

      widget {
        timeseries_definition {
          title = "Memory Usage"
          request {
            q = "avg:system.mem.used{*} by {host}"
          }
        }
      }
    }
  }

  widget {
    alert_graph_definition {
      title = "Alert Status"
      alert_id = datadog_monitor.cpu_high.id
      viz_type = "timeseries"
    }
  }
}
  1. カスタムメトリクスダッシュボード
resource "datadog_dashboard" "custom_metrics" {
  title       = "Application Metrics"
  layout_type = "ordered"

  widget {
    query_value_definition {
      title = "Total Users"
      request {
        q = "sum:custom.users.total{*}"
      }
    }
  }
}

SLOの定義とトラッキング方法

  1. APIレイテンシーSLO
resource "datadog_service_level_objective" "api_latency" {
  name        = "API Latency SLO"
  type        = "monitor"
  description = "Track API endpoint response times"

  thresholds {
    timeframe = "7d"
    target    = 99.9
    warning   = 99.95
  }

  monitor_ids = [
    datadog_monitor.api_latency.id
  ]
}
  1. 可用性SLO
resource "datadog_service_level_objective" "availability" {
  name        = "Service Availability"
  type        = "metric"
  description = "Track service uptime"

  thresholds {
    timeframe = "30d"
    target    = 99.99
    warning   = 99.995
  }

  query {
    numerator   = "sum:http.requests.success{*}"
    denominator = "sum:http.requests.total{*}"
  }
}

実装のポイント:

  • モニターの重要度に応じた通知設定
  • 適切な評価期間とdelay設定
  • メッセージテンプレートの標準化
  • 環境変数による閾値管理
  • タグによる関連付け
  • ダッシュボードの階層化

大規模環境での運用ベストプラクティス

モジュール化による設定の再利用性向上

基本モジュール構造:

# modules/datadog-monitor/variables.tf
variable "environment" {
  type        = string
  description = "環境識別子(prod/stg/dev)"
}

variable "service" {
  type = object({
    name        = string
    team        = string
    criticality = string
  })
}

# modules/datadog-monitor/main.tf
locals {
  common_tags = {
    environment = var.environment
    service     = var.service.name
    team        = var.service.team
    managed_by  = "terraform"
  }
}

resource "datadog_monitor" "service_health" {
  for_each = local.monitor_configs

  name    = "[${var.environment}][${var.service.name}] ${each.value.name}"
  type    = each.value.type
  query   = each.value.query
  message = each.value.message

  monitor_thresholds {
    critical = each.value.thresholds.critical
    warning  = each.value.thresholds.warning
  }

  tags = merge(local.common_tags, each.value.additional_tags)
}

モジュール使用例:

# environments/prod/monitoring.tf
module "api_monitoring" {
  source = "../../modules/datadog-monitor"

  environment = "prod"
  service = {
    name        = "payment-api"
    team        = "platform"
    criticality = "high"
  }

  monitor_configs = {
    cpu = {
      type    = "metric alert"
      query   = "avg(last_5m):avg:system.cpu.user{service:payment-api} by {host} > 85"
      message = "CPU使用率が閾値を超過しています"
      thresholds = {
        critical = 85
        warning  = 75
      }
    }
  }
}

環境別の設定値管理テクニック

# terraform.tfvars.json
{
  "environments": {
    "prod": {
      "thresholds": {
        "cpu": { "critical": 85, "warning": 75 },
        "memory": { "critical": 90, "warning": 80 }
      },
      "notification": {
        "channels": ["#prod-alerts", "@pagerduty-prod"],
        "escalation_minutes": 15
      }
    },
    "stg": {
      "thresholds": {
        "cpu": { "critical": 90, "warning": 80 },
        "memory": { "critical": 95, "warning": 85 }
      },
      "notification": {
        "channels": ["#stg-alerts"],
        "escalation_minutes": 30
      }
    }
  }
}

# variables.tf
locals {
  env_config = lookup(var.environments, terraform.workspace, var.environments["dev"])
}

# モニター定義での使用
resource "datadog_monitor" "cpu_alert" {
  name = "[${terraform.workspace}] CPU Alert"
  query = format(
    "avg(last_5m):avg:system.cpu.user{environment:%s} by {host} > %d",
    terraform.workspace,
    local.env_config.thresholds.cpu.critical
  )
}

チーム間での設定共有のワークフロー

  1. レビュープロセスの自動化
# .github/workflows/terraform.yml
name: Terraform Review
on: [pull_request]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v2

      - name: Terraform Format
        run: terraform fmt -check -recursive

      - name: Terraform Init
        run: |
          for dir in environments/*; do
            if [ -d "$dir" ]; then
              cd $dir
              terraform init -backend=false
              cd ../../
            fi
          done

      - name: Terraform Validate
        run: |
          for dir in environments/*; do
            if [ -d "$dir" ]; then
              cd $dir
              terraform validate
              cd ../../
            fi
          done

      - name: Terraform Plan
        run: |
          for dir in environments/*; do
            if [ -d "$dir" ]; then
              cd $dir
              terraform plan -no-color
              cd ../../
            fi
          done
  1. 変更適用の制御
# backend.tf
terraform {
  backend "s3" {
    bucket         = "terraform-state"
    key            = "datadog/monitoring.tfstate"
    region         = "ap-northeast-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
  }
}

# providers.tf
provider "datadog" {
  api_key = data.aws_ssm_parameter.datadog_api_key.value
  app_key = data.aws_ssm_parameter.datadog_app_key.value

  validate = true
}

data "aws_ssm_parameter" "datadog_api_key" {
  name = "/datadog/${terraform.workspace}/api_key"
}

data "aws_ssm_parameter" "datadog_app_key" {
  name = "/datadog/${terraform.workspace}/app_key"
}

トラブルシューティングとデバッグ

よくあるエラーとその解決方法

  1. 認証エラー
Error: error querying datadog monitor: error querying monitor: API error 403: Forbidden

解決方法:

# 環境変数の確認
printenv | grep DATADOG
# または
echo $DATADOG_API_KEY
echo $DATADOG_APP_KEY

# API/APPキーの再設定
export DATADOG_API_KEY="your_api_key"
export DATADOG_APP_KEY="your_app_key"
  1. リソース競合
Error: error updating datadog dashboard: API error 409: A dashboard with name 'System Overview' already exists

解決方法:

# リソース名の一意性確保
resource "datadog_dashboard" "system_overview" {
  title       = "${var.environment}-${var.service_name}-system-overview"
  layout_type = "ordered"
  # ...
}

デバッグモードを使用した問題解決

  1. 詳細ログの有効化
# デバッグモードでの実行
TF_LOG=DEBUG terraform apply

# ログの保存
TF_LOG=DEBUG TF_LOG_PATH=./terraform.log terraform plan
  1. API通信の確認
provider "datadog" {
  api_key = var.datadog_api_key
  app_key = var.datadog_app_key

  # APIリクエストの検証を有効化
  validate = true

  # タイムアウト設定
  api_timeout = 30
}

設定変更の安全な適用方法

  1. 変更計画の検証
# 詳細な差分確認
terraform plan -detailed-exitcode

# 特定リソースのみ確認
terraform plan -target=datadog_monitor.cpu_high
  1. 段階的なロールアウト
# テスト用モニターの作成
resource "datadog_monitor" "test_monitor" {
  count = terraform.workspace == "dev" ? 1 : 0

  name    = "Test Monitor"
  type    = "metric alert"
  message = "Test alert message"

  query = "avg(last_5m):avg:system.cpu.user{environment:dev} by {host} > 90"
}

# 本番適用前の検証
locals {
  is_production = terraform.workspace == "prod"

  monitor_thresholds = {
    dev = {
      critical = 90
      warning  = 80
    }
    prod = {
      critical = 85
      warning  = 75
    }
  }
}
  1. ロールバック戦略
# 状態の確認
terraform show

# 特定バージョンへの戻し方
git checkout <previous_commit>
terraform plan
terraform apply

実装のポイント:

  • エラーメッセージの詳細な解析
  • ステート管理の定期的な確認
  • バックアップの保持
  • 変更履歴のドキュメント化