Automating Grafana Dashboards on Azure with Terraform — Part 1: Provisioning an Azure Managed Grafana Instance
I love mashing up Terraform providers. It’s one of the superpowers of Terraform that no other first-party infrastructure-as-code tool has been able to replicate. Bicep is trying with the recent introduction of Entra ID support, but it seems unlikely that Bicep-alone will be able to replicate the kind of ecosystem that Terraform has. There’s something about being on neutral territory like Terraform. Maybe the Swiss got the right idea after all?
So, one of the provider mashups that I have hands-on experience with is Azure and Grafana. I, of course, use the Azure provider all the time but I encountered a scenario where I was using Azure Managed Grafana to spin up Grafana dashboards for some telemetry dashboards at work. That’s when I discovered the Grafana provider — and boy, was I surprised! The Grafana provider is big — and when I say big, I mean BIG. I was expecting a small, immature provider with very few resources but, boy, was I wrong. It has tons of resources. It seems like every bell and whistle within Grafana can be managed by this thing — and from my experience, I’m happy to report that it seems very mature by my standards.
I had so much fun using it I decided to pitch it as one of my talk proposals for HashiDays 2024. I was not expecting to be selected because it’s not exactly a super sexy topic — nor does it fall into the “meat and potatoes” category for Terraform talks either. However, I was shocked to discover that my little talk about Terraforming Grafan had been selected! Hooray!
Just one slight twist, I had to fly 30 hours (one way) to give my 30-minute talk, because I had been selected for HashiDays Sydney. In the words of my generation: “No problemo!” The Azure Terraformer is up for anything!
IMAGE
So, I flew down to Sydney Australia in June of 2024 for HashiDays 2024 and gave my talk. It was the biggest stage I had ever been on. Lots of big lights. Big dark room. Wireless mic. Heads-up speaker displays at my feet in case you forgot your lines — who’s line is it anyway?
IMAGE
Made some good friends down there in Sydney and can’t wait to go back!
IMAGE
Catch me making a fool of myself live at HashiDays 2024 — though, let’s be real, it’s just another day at the office for my YouTube channel!
IMAGE
So how do we get started with all this?
The first thing you have to do is to provision a Grafana Azure Grafana Managed Instance using the azurerm provider. Now in this example I am using a “System Assigned” managed identity, but I would recommend you use azurerm_user_assigned_identity and create your own Managed Identity explicitly to assign permissions to. I’ve never been a fan of System Assigned identity. I much prefer always creating my own User Assigned Managed Identities. To me, it feels like I am in more control — but maybe that’s just my OCD talking.
resource "azurerm_dashboard_grafana" "main" {
name = "amg-${var.application_name}-${var.environment_name}"
resource_group_name = azurerm_resource_group.main.name
location = azurerm_resource_group.main.location
api_key_enabled = true
deterministic_outbound_ip_enabled = true
public_network_access_enabled = true
identity {
type = "SystemAssigned"
}
}
Next you need to grant the Grafana Managed Identity access to Azure Monitor. I’ll probably address this in a future blog post where I show you how to setup Grafana Data sources. One of the most useful Grafana Data Sources (for Azure users) is the Azure Monitor Data Source, which allows you to create dashboards based off, you guessed it, Azure Monitor data.
resource "azurerm_role_assignment" "grafana_monitoring_reader" {
scope = data.azurerm_subscription.current.id
role_definition_name = "Monitoring Reader"
principal_id = azurerm_dashboard_grafana.main.identity.0.principal_id
}
Grafana is one of those services that once you provision it, it comes with its own console and basically you (and your users) are all going to access it using that console. It’s important to note that this console is essentially a public web site, unless you turn of public access — but that is a talk for another day. The good news is that this public access will automatically be setup to allow Entra ID users to access it. This is probably one of the big perks of using the Azure Managed Grafana to host your Grafana instances.
Now when setting up access we should at least plan for two classes of users: Administrators who will create dashboards and manage the Grafana cluster and Users who will view the dashboards. We can simply pass in an Entra ID Group ID — or better yet, look it up using a data source and create a role assignment for the scope of our Grafana Managed Instance for the “Grafana Admin” role. You should check the official documentation for other roles to use for other purposes.
resource "azurerm_role_assignment" "grafana_access" {
scope = azurerm_dashboard_grafana.main.id
role_definition_name = "Grafana Admin"
principal_id = var.administrator_group_id
}
Now, because we eventually plan on managing this Grafana Managed Instance using Terraform we need to grant the Terraform user access to Grafana. Of course, Terraform needs to be an administrator as well.
resource "azurerm_role_assignment" "terraform_grafana_access" {
scope = azurerm_dashboard_grafana.main.id
role_definition_name = "Grafana Admin"
principal_id = data.azurerm_client_config.current.object_id
}
That’s it! Now we are ready to provision the Grafana Managed Instance to Azure and start configuring a new Terraform workspace to manage all the Grafana things using the Grafana Terraform provider. I’ll cover that in Part 2 of the Great Azure Managed Grafana Terraform Saga.
Until then — Happy Azure Terraforming!