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
実装のポイント:
- エラーメッセージの詳細な解析
- ステート管理の定期的な確認
- バックアップの保持
- 変更履歴のドキュメント化