Diary of a Perpetual Student

Perpetual Student: A person who remains at university far beyond the normal period

MackerelのカスタムダッシュボードをTerraformで作る

arthur-1 Mackerel Advent Calendar 2023ラソン7日目の記事です。

カスタムダッシュボードもTerraformで管理

2023年1月ごろリリースされたTerraform Provider Mackerel v0.3.0より、MackerelのカスタムダッシュボードをTerraformで管理することができるようになりました。

https://registry.terraform.io/providers/mackerelio-labs/mackerel/latest/docs/resources/dashboard

残念なことに、この機能はあまり使われていないと感じています。そう感じる理由は、実際に自分が使ってみて特定の条件でpanicすることがあるなどの問題があるのに気づいたのですが、それらがこれまでユーザーのみなさまからフィードバックされて来なかったからです。自分が見つけたcriticalな問題に関しては修正するPull Requestを出していました。

github.com

今回は、カスタムダッシュボードをTerraformで管理するメリットと、テクニックについて説明します。

Terraformで管理するメリット

これは大体IaCのメリットそのものなのですが、カスタムダッシュボードというケースにおいてどう嬉しいのかを書いていきます。

ダッシュボードの変更履歴をgitに残せる

MackerelのダッシュボードはGUIで作成・編集している人がほとんどだと思いますが、それだと編集履歴が残りません。ダッシュボードをコードとして管理することで、gitやsvnなどでバージョン管理することができます。

また、GitHubのPull Requestなどに、ダッシュボードをどのように変更したか、その変更は何のためなのか、という情報が蓄積していきます。メトリックをどのようにみるべきかという情報に関してはPull Request上ではなくダッシュボード上にMarkdownウィジェットなどとして記述されていて欲しいです。しかし、中にはダッシュボードには載せるまでもないけど歴史的経緯はいつか参照し得るので記録しておきたいということもあるでしょう。そういったときにダッシュボードがコードで管理されていると便利です。

環境ごとにダッシュボードのvariantを作れる

カスタムダッシュボードのresourceを含んだmoduleを作り、ホストIDやサービス名などをvariableにすることで、それぞれ環境は違うものの構成が同じダッシュボードを複数個簡単に作ることができます。

環境ごとインフラを手動で作ると同じ構成で作るのが大変なのでTerraformを使っているという人も多いと思います。監視に関してもそれは同じだと感じています。

ウィジェットを複製するテクニック

カスタムダッシュボードそのものを複製することができるのと同様に、あるダッシュボードに含まれるウィジェットを複製して作ることも可能です。ダッシュボードがresourceであるとは異なりウィジェットはresource parameterなので、以下のようにdynamic blockを用いることで、1つの定義からウィジェットをたくさん作って配置することができます。

locals {
  services = [
    {
      index = 0,
      name  = "ServiceA",
    },
    {
      index = 1,
      name  = "ServiceB",
    },
    {
      index = 2,
      name  = "ServiceB",
    },
  ]
  markdown_widget_height = 2
}

resource "mackerel_dashboard" "this" {
  title    = "hogehoge"
  memo     = "poyo"
  url_path = "hogehoge"

  dynamic "markdown" {
    for_each = { for i in local.services : i.name => i }
    content {
      title    = ""
      markdown = <<-EOT
      ## ${markdown.value.name}
      EOT
      layout {
        x      = 0
        y      = local.markdown_widget_height * markdown.value.index
        width  = 24
        height = local.markdown_widget_height
      }
    }
  }
}

このように書いてterraform applyすると、以下のようにMarkdownウィジェットが縦に並びます:

実際に作り込もうとすると配置の計算などを試行錯誤することになると思いますが、何度でもapplyして実験してみましょう。一般的なエディタでは編集履歴が残っていてUndoできるので、ちょっとしたロールバックもやりやすいと思います。