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
による変更影響の事前確認- 必要に応じた設定の巻き戻し
変更管理のベストプラクティス:
- ブランチ運用による変更の分離
- terraform planの結果をPRにコメント
- 承認フローと連携した適用管理
- 変更履歴の文書化
Terraform Datadog Providerの基本設定
API キーと Application キーの取得方法
Datadogとの連携に必要なキーは以下の手順で取得できます:
- API キーの取得
- Datadogコンソールの[Organization Settings] > [API Keys]に移動
- [New Key]をクリックして新規API キーを作成
- キーの用途に応じて適切な名前を設定(例:
terraform-integration
)
- 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 }
基本的なリソース定義の書き方
- モニターの基本定義
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"] }
- ダッシュボードの基本定義
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" } } } }
- タグの付与規則
# グローバルタグの定義例 resource "datadog_monitor" "tagged_monitor" { # ... 基本設定 ... tags = concat( var.global_tags, [ "service:${var.service_name}", "env:${var.environment}", "managed-by:terraform" ] ) }
実装のポイント:
- リソース名は明確で一貫性のある命名規則を使用
- 必要な属性は全て明示的に指定
- デフォルト値に依存しない
- 変数化して再利用可能な設計に
実践的なDatadogリソース定義 – 20個の実例付き
モニターの定義と閾値設定のベストプラクティス
- マルチアラート 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"] }
- メモリリーク検知モニター
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}}" }
- ディスク使用量予測モニター
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" }
ダッシュボード作成の自動化テクニック
- システム概要ダッシュボード
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" } } }
- カスタムメトリクスダッシュボード
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の定義とトラッキング方法
- 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 ] }
- 可用性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 ) }
チーム間での設定共有のワークフロー
- レビュープロセスの自動化
# .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
- 変更適用の制御
# 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" }
トラブルシューティングとデバッグ
よくあるエラーとその解決方法
- 認証エラー
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"
- リソース競合
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" # ... }
デバッグモードを使用した問題解決
- 詳細ログの有効化
# デバッグモードでの実行 TF_LOG=DEBUG terraform apply # ログの保存 TF_LOG=DEBUG TF_LOG_PATH=./terraform.log terraform plan
- API通信の確認
provider "datadog" { api_key = var.datadog_api_key app_key = var.datadog_app_key # APIリクエストの検証を有効化 validate = true # タイムアウト設定 api_timeout = 30 }
設定変更の安全な適用方法
- 変更計画の検証
# 詳細な差分確認 terraform plan -detailed-exitcode # 特定リソースのみ確認 terraform plan -target=datadog_monitor.cpu_high
- 段階的なロールアウト
# テスト用モニターの作成 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 } } }
- ロールバック戦略
# 状態の確認 terraform show # 特定バージョンへの戻し方 git checkout <previous_commit> terraform plan terraform apply
実装のポイント:
- エラーメッセージの詳細な解析
- ステート管理の定期的な確認
- バックアップの保持
- 変更履歴のドキュメント化