これは、なにをしたくて書いたもの?
最近OpenTelemetryまわりを扱う時にGrafanaが出てくるのですが、このセットアップを毎回Web UIで操作して行うのが面倒だなと思いまして。
Terraformでなんとかならないかな?と思って見てみたら、Grafana自身がTerraformのProviderを提供しているようなのでこちらを
使ってみることにしました。
Terraform Provider for Grafana
Terraform Provider for Grafanaのドキュメントはこちら。
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を操作してみます。
参照するドキュメントはこちら。
今回はこんな感じで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
- Authentication options for the HTTP API | Grafana documentation
- Service accounts | Grafana documentation
今回は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)
今回の場合、データソースに指定するのはname、type、urlくらいでよいのですが、Prometheusのところだけ少し追加の設定を入れています。
例というところですが。またデフォルトのデータソースはPrometheusにしました。
各データソースに対してなにを指定したらいいのかgrafana_data_sourceリソースのドキュメントを見てもよくわからないので、Grafanaの
HTTP APIに関するドキュメントを見ることになります。
Data source HTTP API | Grafana documentation
が、ここを見ても情報が足りないので、各データソースのプロビジョニングのサンプルを見ることになります。
Data sources | Grafana documentation
- Configure a Tempo data source / Provision the data source
- Configure the Prometheus data source / Provision the Prometheus data source
さらに言うと、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で操作できると便利ですね。
今後、使っていこうと思います。