Grafana Series - GaC 2 - Grafana Terraform Provider Basics
This article was last updated on: May 17, 2026 am
Series Articles
Overview
In the previous article, I summarized my tool selection:
- Grafana Terraform provider
- Jsonnet
Today, let’s start with a brief introduction to the Grafana Terraform provider.
Grafana Terraform Provider
The Grafana provider offers configuration management resources for Grafana. It is currently the officially maintained IaC tool with the most comprehensive coverage of Grafana resources.
The Grafana Terraform Provider is built on top of grafana-api-golang-client.
With the Grafana Terraform Provider, we can manage:
- Alerting
- Resources
- grafana_contact_point
- grafana_message_template
- grafana_mute_timing
- grafana_notification_policy
- grafana_rule_group
- Resources
- Cloud
- Resources
- grafana_cloud_access_policy
- grafana_cloud_access_policy_token
- grafana_cloud_api_key
- grafana_cloud_plugin_installation
- grafana_cloud_stack
- grafana_cloud_stack_api_key
- grafana_cloud_stack_service_account
- grafana_cloud_stack_service_account_token
- grafana_machine_learning_holiday
- grafana_machine_learning_job
- grafana_machine_learning_outlier_detector
- DataSources
- grafana_cloud_ips
- grafana_cloud_organization
- grafana_cloud_stack
- Resources
- Grafana Enterprise
- Resources
- grafana_builtin_role_assignment
- grafana_data_source_permission (AWS Managed Grafana also supports this feature)
- grafana_report
- grafana_role
- grafana_role_assignment
- grafana_team_external_group
- Resources
- Grafana OSS
- Resources
- grafana_annotation
- grafana_api_key
- grafana_dashboard
- grafana_dashboard_permission
- grafana_data_source
- grafana_folder
- grafana_folder_permission
- grafana_library_panel
- grafana_organization
- grafana_organization_preferences
- grafana_playlist
- grafana_service_account
- grafana_service_account_permission
- grafana_service_account_token
- grafana_team
- grafana_team_preferences
- grafana_user
- DataSources
- grafana_dashboard
- grafana_dashboards
- grafana_data_source
- grafana_folder
- grafana_folders
- grafana_library_panel
- grafana_organization
- grafana_organization_preferences
- grafana_team
- grafana_user
- grafana_users
- Resources
- OnCall
- Omitted
- SLO
- Omitted
- Synthetic Monitoring
- Omitted
Hands-On
Since Grafana resources are relatively straightforward and independent — unlike AWS, which often involves complex interdependencies — the organization of Grafana TF code can be kept simple:
- You can use a single AllInOne .tf file
- Or split by resource type into something like:
1 | |
Let’s walk through the details using the second organizational structure.
Creating the Grafana Provider
In main.tf, create the Grafana Provider:
1 | |
If you only have one Grafana instance, the configuration above is all you need.
If you have multiple Grafana instances, you can use the alias parameter of the Grafana provider. Here’s how:
1 | |
When using resources later, you can specify the provider to distinguish between instances, like this:
1 | |
│ 📝Notes:
│ For brevity in the following examples, we won’t show the multi-provider scenario.
│ Resources will not include the provider field.
To use Grafana with Terraform, you need to provide at least a URL and an API key. These can be supplied via environment variables as follows:
1 | |
The value of GRAFANA_AUTH can be a Grafana API key, basic auth in the format username:password, or you can follow this link to create a Grafana API key.
Additionally, Grafana Cloud, Synthetic Monitoring, and Grafana OnCall each have their own dedicated API keys or tokens, which we won’t cover in detail here.
Creating a Grafana Organization
│ 📝Notes:
│
│ Since I primarily use AWS Managed Grafana, which only has a single default org (org 1) and doesn’t expose the ability to create multiple organizations, I rarely use this resource.
If you do need this resource, you can create an org.tf file with the following content:
1 | |
Creating DataSources
The required parameters for this resource vary depending on the selected data source type (specified via the type parameter).
These can be created in datasource.tf.
Below are simple examples for creating:
- stackdriver
- influxdb
- cloudwatch
- zabbix
- ES
- Prometheus
- Jaeger
Stackdriver
1 | |
Influxdb
1 | |
Cloudwatch
Creating with AKSK (Access Key / Secret Key):
1 | |
Creating with an IAM role (external):
1 | |
Zabbix
1 | |
│ 🐾 Note:
│
│ The Zabbix type is alexanderzobnin-zabbix-datasource.
│ A prerequisite is installing the Zabbix Grafana Plugin.
Jaeger
1 | |
📝 The data “grafana_data_source” “jaeger-example” block above exposes the Jaeger DataSource UID for use by ES.
Of course, if you specify the uid directly when creating the Jaeger DataSource, as shown below, you can hardcode it when referencing it from other DataSources.
1 | |
ES
1 | |
There are a few things to note here:
- database_name = “[example.*-]YYYY.MM.DD” — when the type is ES, database_name refers to the ES index name.
- dataLinks — this links to the Jaeger DataSource via a data link: datasourceUid = data.grafana_data_source.jaeger-example.uid (the Jaeger DataSource was created in the previous section).
- url = “${”$“}{__value.raw}” — pay special attention here. The actual value passed to Grafana is ${__value.raw}, but this also happens to be Terraform’s template/variable interpolation syntax. Writing it directly would cause Terraform to try to resolve it as a variable, resulting in an error. By using ${“$”} to escape the $, it becomes $ + {__value.raw}, producing the correct ${__value.raw} for Grafana.
Prometheus
Basic configuration:
1 | |
Configuration for Mimir, the official Prometheus-compatible implementation by Grafana:
1 | |
Creating Dashboards
In dashboard.tf, here’s an example of creating a dashboard:
1 | |
You can also create one like this:
1 | |
🐾 Note:
config_json is a String type that takes the complete Dashboard model JSON.
You can load it directly using file(“grafana-dashboard.json”).
As shown in the second example, jsonencode converts an object to a JSON string.
Summary
In this article, we covered the basics of the Grafana Terraform Provider. It’s fairly straightforward — we used it to:
- Create a Provider
- Create an Organization
- Create Folders
- Create various common DataSources
- Create Dashboards
Very clear and intuitive. Hope this helps!
📚️ References
- Docs overview | grafana/grafana | Terraform Registry
- grafana_folder | Resources | grafana/grafana | Terraform Registry
- grafana_data_source | Resources | grafana/grafana | Terraform Registry
- grafana_dashboard | Resources | grafana/grafana | Terraform Registry
- jsonencode - Functions - Configuration Language | Terraform | HashiCorp Developer
- Strings and Templates - Configuration Language | Terraform | HashiCorp Developer