goodbyegangsterのブログ

備忘録的な

DatadogをTerraformで操作する

TerraformでDatadogを操作する Datadog Provider を利用して、DatadogのMonitor設定を試してみます。

公式ページはこちら。

Provider: Datadog - Terraform by HashiCorp

Datadog社の紹介ブログです。

Managing Datadog with Terraform | Datadog

環境

  • Windows10 Pro
  • Terraform v0.11.13
    • datadog provider (1.8.0)
    • template provider (2.1.1)

試してみる

基本的に、上に貼ったページを見て進めれば、簡単に設定できます。以下は、CPU使用率を監視するMonitor設定例となります。設定におけるメモとしては...

  • providerディレクティブで datadog を指定して、DatadogのAPIキーとAPPキーを登録
  • resourceディレクティブで、 monitor を指定して、設定したい属性を登録
    • 各属性については、以下のマニュアルを参照
    • Datadog: datadog_monitor - Terraform by HashiCorp
    • それぞれ属性にはデフォルト値が定められているので、明示的に指定しない場合、そのデフォルト値が利用される

tfファイルはこんな感じ。

provider "datadog" {
  api_key = "XXXXXXXXXXXXXXXXXXXXXX"
  app_key = "XXXXXXXXXXXXXXXXXXXXXX"
}

resource "datadog_monitor" "cpumonitor" {

  name = "cpu monitor"
  type = "metric alert"
  message = "CPUアラートだよ"
  query = "max(last_5m):100 - avg:system.cpu.idle{*} by {host,name} > 90"

  thresholds {
    ok = 70
    warning = 80
    critical = 90
  }

}

これで、 terraform apply すれば、Monitorを作成してくれます。便利ですね。

最適なディレクトリ/tfファイル戦略を考える

システムにおいて監視Monitorが1つだけというのは有り得ないので、Monitorが多数ある場合も想定して、最適なディレクトリ/tfファイル戦略を考えます。以下の点を考慮しています。

  • Datadogの、APIキー・APPキーは変数化したい
  • Monitor種類毎に、tfファイルを別けたい
    • tfstateファイルを別けたい
  • MonitorのMessageにあたるアラート発生時の通知文章部分を、可能な限りテンプレート化したい
  • 被監視対象の環境はAWSを想定

で、とりあえず考えついたディレクトリ構造はこんな感じです。

.
├── EC2
│   ├── main.tf
│   └── datadog.auto.tfvars -> ../datadog.auto.tfvars
├── RDS
│   ├── main.tf
│   └── datadog.auto.tfvars -> ../datadog.auto.tfvars
├── message
│   ├── event_01.md.tpl
│   └── metric_01.md.tpl
└── datadog.auto.tfvars

考えた方針です。


実際のファイルたちです。

datadog.auto.tfvars

datadog_api_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
datadog_app_key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxXxxxx"
  • Datadogの各keyを設定する変数ファイル

./EC2/main.tf

variable "datadog_api_key" {}
variable "datadog_app_key" {}

provider "datadog" {
  api_key = "${var.datadog_api_key}"
  app_key = "${var.datadog_app_key}"
}

##############################
## EC2ヘルスチェック監視
##############################

data "template_file" "ec2_healthccheck" {
  template = "${file("../message/event_01.md.tpl")}"

  vars {
    server_name = "{{host.name}}"
    event_name = "EC2ヘルスチェック"
  }
}

resource "datadog_monitor" "ec2_healthccheck" {

  name = "ec2 healthccheck {{host.name}}"
  type = "metric alert"
  message = "${data.template_file.ec2_healthccheck.rendered}"
  query = "max(last_5m):avg:aws.ec2.status_check_failed_system{*} by {host,name} > 0"

}

##############################
## CPU監視
##############################

data "template_file" "cpu_monitor" {
  template = "${file("../message/metric_01.md.tpl")}"

  vars {
    server_name = "{{host.name}}"
    event_name = "CPU使用率"
    metric_value = "{{value}}"
  }
}

resource "datadog_monitor" "cpu_monitor" {

  name = "cpu monitor {{host.name}}"
  type = "metric alert"
  message = "${data.template_file.cpu_monitor.rendered}"
  query = "max(last_5m):100 - avg:system.cpu.idle{*} by {host,name} > 90"

}
  • EC2用のMonitorを設定するtfファイル
  • Datadog用Key情報を、変数ファイルから呼び出しています
  • template providerとfile functionを利用して、messageに登録する内容を呼び出しています
    • templateで利用する文章は、file functionを利用して定型文を呼び出す方法に
    • 定型文内で、Monitor毎にカスタマイズしたい部分を変数としておいて、tfファイル内で設定しています

./message/event_01.md.tpl

こんにちは。東北ずん子がアラートをお伝えします。
{{last_triggered_at}} (UTC) の時刻にて、
東北システムの ${server_name} サーバーにて、 ${event_name} のイベントが発生しています。
ご確認ください。\(ず・ω・だ)/
  • tfファイルで呼び出されているテンプレートファイル
  • 通知文としたい文章フォーマットをいくつか用意して、Monitor毎に変更したい値を変数として登録
  • Datadog Monitorのメッセージ部分は、Markdownフォーマットで記載できます
    • なので分かりにくいけど、改行するために、文末にスペース2つ付けてます

./message/metric_01.md.tpl

こんにちは。東北ずん子がアラートをお伝えします。
{{last_triggered_at}} (UTC) の時刻にて、
東北システムの ${server_name} サーバーにて、 ${event_name} のメトリクス超過が発生しました。値は、${metric_value}となります。
ご確認ください。\(ず・ω・だ)/

これで terraform apply をすれば、Monitor設定をしてくれます。

f:id:goodbyegangster:20190416230713p:plain

messageの定型文として処理する方法について、template providerとfile functionをいい感じに利用する方法について、以下のブログを参考にさせて頂きました。ありがとうございました。

Terraformで外部の設定ファイルから設定を読み込む(file, template_file, template_cloudinit_config) - woshidan's blog