CLOVER🍀

That was when it all began.

Terraform Provider for Grafanaを使って、GrafanaをTerraformで操作してみる

これは、なにをしたくて書いたもの?

最近OpenTelemetryまわりを扱う時にGrafanaが出てくるのですが、このセットアップを毎回Web UIで操作して行うのが面倒だなと思いまして。

Terraformでなんとかならないかな?と思って見てみたら、Grafana自身がTerraformのProviderを提供しているようなのでこちらを
使ってみることにしました。

Terraform Provider for Grafana

Terraform Provider for Grafanaのドキュメントはこちら。

Grafana Provider

GitHubリポジトリーはこちらです。

GitHub - grafana/terraform-provider-grafana: Terraform Grafana provider

ドキュメントを見ていると、GrafanaというよりGrafanaが提供する様々なソフトウェアやサービスに対するTerraform Providerのようですね。

今回はGrafana OSSを対象にします。

お題

お題としては、PrometheusとGrafana TempoをGrafanaのデータソースとして追加してみることにします。

環境

今回の環境はこちら。

Terraform。

$ terraform version
Terraform v1.12.2
on linux_amd64

Grafana。172.19.0.6で動作しているものとします。

$ grafana-server --version
Version 12.1.1 (commit: df5de8219b41d1e639e003bf5f3a85913761d167, branch: release-12.1.1)

Grafana Tempo。172.19.0.3で動作しているものとします。

$ tempo --version
tempo, version 2.8.2 (branch: HEAD, revision: 6b9261586)
  build user:
  build date:
  go version:       go1.24.5
  platform:         linux/amd64
  tags:             unknown

Prometheus。172.19.0.5で動作しているものとします。

$ ./prometheus --version
prometheus, version 3.5.0 (branch: HEAD, revision: 8be3a9560fbdd18a94dedec4b747c35178177202)
  build user:       root@4451b64cb451
  build date:       20250714-16:15:23
  go version:       go1.24.5
  platform:         linux/amd64
  tags:             netgo,builtinassets

Grafana TempoやPrometheusについては今回あまり重要ではないので、以降はデータソースに関する情報くらいしか触れないことにします。

Terraform Provider for Grafanaを使ってみる

それでは、Terraform Provider for Grafanaを使ってGrafanaを操作してみます。

参照するドキュメントはこちら。

Grafana Provider

今回はこんな感じでTerraform構成ファイルを作成しました。

terraform.tf

terraform {
  required_version = "1.12.2"

  required_providers {
    grafana = {
      source  = "grafana/grafana"
      version = "4.5.1"
    }
  }
}

main.tf

provider "grafana" {
  url  = "http://172.19.0.6:3000"
  auth = "admin:admin"
}

resource "grafana_data_source" "tempo" {
  name = "tempo"
  type = "tempo"
  url  = "http://172.19.0.3:3200"
}

resource "grafana_data_source" "prometheus" {
  name = "prometheus"
  type = "prometheus"
  url  = "http://172.19.0.5:9090"

  is_default = true

  json_data_encoded = jsonencode({
    httpMethod     = "POST"
    prometheusType = "Prometheus"
  })
}

output "datasource_tempo_uid" {
  value = grafana_data_source.tempo.uid
}

output "datasource_prometheus_uid" {
  value = grafana_data_source.prometheus.uid
}

順に見ていきましょう。

まずはproviderで、操作するGrafanaのURLとauthで認証情報を設定します。

provider "grafana" {
  url  = "http://172.19.0.6:3000"
  auth = "admin:admin"
}

authに設定するのは、Basic認証を使ってユーザー名とパスワードを設定するか、サービスアカウントのトークンを設定します。

This can be a Grafana API key, basic auth username:password, or a Grafana Service Account token.

Grafana Provider / Authentication / auth

今回はBasic認証前提にしています。

次はデータソースです。

resource "grafana_data_source" "tempo" {
  name = "tempo"
  type = "tempo"
  url  = "http://172.19.0.3:3200"
}

resource "grafana_data_source" "prometheus" {
  name = "prometheus"
  type = "prometheus"
  url  = "http://172.19.0.5:9090"

  is_default = true

  json_data_encoded = jsonencode({
    httpMethod     = "POST"
    prometheusType = "Prometheus"
  })
}

grafana_data_source (Resource)

今回の場合、データソースに指定するのはnametypeurlくらいでよいのですが、Prometheusのところだけ少し追加の設定を入れています。
例というところですが。またデフォルトのデータソースはPrometheusにしました。

各データソースに対してなにを指定したらいいのかgrafana_data_sourceリソースのドキュメントを見てもよくわからないので、Grafanaの
HTTP APIに関するドキュメントを見ることになります。

Data source HTTP API | Grafana documentation

が、ここを見ても情報が足りないので、各データソースのプロビジョニングのサンプルを見ることになります。

Data sources | Grafana documentation

さらに言うと、1度手動で作成してcurlあたりで定義を取得した方がわかりやすいでしょうね…。

json_data_encodedなどをgrafana_data_source_configリソースに切り出して定義することもあるようです。

grafana_data_source_config (Resource)

では、リソースを作成しましょう。

$ terraform init
$ terraform apply

データソースのuidが得られました。

Outputs:

datasource_prometheus_uid = "eev9zhpm4pnnkc"
datasource_tempo_uid = "bev9zhpm77k00d"

Grafanaを見てみると、ちゃんとデータソースが作成できています。

curlでデータソース定義を取得してみます。

Prometheus。

$ curl -s -H 'Content-Type: application/json' -u admin:admin 172.19.0.6:3000/api/datasources/uid/eev9zhpm4pnnkc | jq
{
  "id": 1,
  "uid": "eev9zhpm4pnnkc",
  "orgId": 1,
  "name": "prometheus",
  "type": "prometheus",
  "typeLogoUrl": "public/plugins/prometheus/img/prometheus_logo.svg",
  "access": "proxy",
  "url": "http://172.19.0.5:9090",
  "user": "",
  "database": "",
  "basicAuth": false,
  "basicAuthUser": "",
  "withCredentials": false,
  "isDefault": false,
  "jsonData": {
    "httpMethod": "POST",
    "prometheusType": "Prometheus"
  },
  "secureJsonFields": {},
  "version": 1,
  "readOnly": false,
  "apiVersion": ""
}

Grafana Tempo。

$ curl -s -H 'Content-Type: application/json' -u admin:admin 172.19.0.6:3000/api/datasources/uid/bev9zhpm77k00d | jq
{
  "id": 2,
  "uid": "bev9zhpm77k00d",
  "orgId": 1,
  "name": "tempo",
  "type": "tempo",
  "typeLogoUrl": "public/plugins/tempo/img/tempo_logo.svg",
  "access": "proxy",
  "url": "http://172.19.0.3:3200",
  "user": "",
  "database": "",
  "basicAuth": false,
  "basicAuthUser": "",
  "withCredentials": false,
  "isDefault": true,
  "jsonData": {},
  "secureJsonFields": {},
  "version": 1,
  "readOnly": false,
  "apiVersion": ""
}

ちなみに、データソースのuidはGrafanaのWeb UI上でデータソースにアクセスした時にパスに含まれているのでこちらで確認できます。

http://[Grafanaが動作しているホスト]:3000/connections/datasources/edit/[uid]

簡単にですが、ひとまずこんなところでしょうか。

おわりに

Terraform Provider for Grafanaを使って、GrafanaをTerraformで操作してみました。

Grafanaをプロビジョニングする度にWeb UIで操作するのが面倒になってきていたので、こうやってTerraformで操作できると便利ですね。
今後、使っていこうと思います。