Configure serverless Azure Metrics with Terraform
Complete the following steps to configure serverless Azure metrics using Terraform.
Configure Azure authorization
To collect metrics from Azure Monitor, create a service principal with the proper authorization to allow Grafana Cloud to pull Azure metrics on your behalf.
Create a service principal with Azure CLI
Log in to your Azure account.
az loginList your available subscriptions.
az account list --output tableCreate a service principal for each subscription you want to monitor, and give it the appropriate role. If a service principal already exists with this name, it is updated with the role and scopes you provide. Replace
<subscription-id>with the appropriate value and use the following command:az ad sp create-for-rbac --name grafana-cloud-azure-metrics --role "Monitoring Reader" --scopes "/subscriptions/{subscriptionId}"When the service principal is created, save the output of the command to use as the credential information that you need for the Terraform configuration steps.
{ "appId": "54321a67-8fd9-123d-45d6-7891234567fd", "displayName": "grafana-cloud-azure-metrics", "password": "asdf1234~4321fdsa", "tenant": "12345a67-8fd9-123d-45d6-7891234567fd" }
Create a service principal with Terraform
The following snippet shows how to configure the Azure service principal using Terraform. You do not need to apply the Terraform to create the service principal before moving forward.
data "azurerm_client_config" "current" {}
resource "azuread_application" "grafana_cloud_azure_metrics" {
display_name = "grafana-cloud-azure-metrics"
}
resource "azuread_application_password" "grafana_cloud_azure_metrics" {
application_id = azuread_application.grafana_cloud_azure_metrics.client_id
end_date_relative = "8760h" # 1 year
}
resource "azurerm_role_assignment" "grafana_cloud_azure_metrics" {
scope = "/subscriptions/<subscription-id>"
role_definition_name = "Monitoring Reader"
principal_id = azuread_application.grafana_cloud_azure_metrics.client_id
}Configure Grafana Cloud
After deciding how you want to configure the Azure service principal, you can configure Grafana Cloud to use it.
Create an Access Policy for the Grafana Terraform provider
If you are already using the Grafana Terraform provider, ensure the access policy you are using has the following scopes:
orgs: Readstacks: Readaccesspolicies: Read, Write, Delete
If you haven’t used the Grafana Terraform provider yet, you must create an access policy. Since this access policy is necessary to use the Terraform provider, you must create it through Grafana Cloud.
Follow the steps to Create access policies and tokens.
Use the Add scopes drop-down to add the following specific scopes to the access policy for Grafana to have the access it needs to integrate with your cloud provider:
integration-management:readintegration-management:writestacks:read
On your Grafana Cloud access policy, click Add token to generate a token to authenticate the provider with the Cloud Provider API. Give your token an appropriate name and select an Expiration date.
We recommend you select a specific expiration date and do not set the Expiration date to No expiry, as this can create a security vulnerability.
Configure the Grafana Terraform provider with your Access Policy
Include the Grafana Terraform provider as a dependency in your Terraform configuration file.
The version of the provider must be 3.18.0 or later, as in the following example:
terraform {
required_providers {
grafana = {
source = "grafana/grafana"
version = ">= 3.18.0"
}
}
}Choose one of the following methods to configure the Grafana Terraform provider to use the provisioned Access Policy token:
- Embed the token in Terraform configuration, as in the following example:
provider "grafana" {
cloud_access_policy_token = "<cloud_access_policy_token_from_previous_step>"
}- Use the environment variable
GRAFANA_CLOUD_ACCESS_POLICY_TOKENset to the created token when running Terraform commands with the following provider block:
provider "grafana" {}Configure the Terraform provider to use the Cloud Provider API
We suggest creating a dedicated access policy for interacting with the Cloud Provider API through the Terraform provider. The following snippet shows how to configure the access policy using Terraform. You do not need to apply the Terraform to create the access policy before moving forward.
provider "grafana" {
}
data "grafana_cloud_organization" "current" {
slug = "<org-slug>"
}
data "grafana_cloud_stack" "current" {
slug = "<stack-slug>"
}
resource "grafana_cloud_access_policy" "cloud_provider_policy" {
region = data.grafana_cloud_stack.current.region_slug
name = "cloud-provider-terraform"
display_name = "Access policy used for Cloud Provider o11y setup"
scopes = ["integration-management:read", "integration-management:write", "stacks:read"]
realm {
type = "org"
identifier = data.grafana_cloud_organization.current.id
}
}
resource "grafana_cloud_access_policy_token" "cloud_provider_token" {
region = data.grafana_cloud_stack.current.region_slug
access_policy_id = grafana_cloud_access_policy.cloud_provider_policy.policy_id
name = "cloud-provider-terraform"
display_name = "Token used for Cloud Provider o11y setup"
}
provider "grafana" {
alias = "cloud_provider"
cloud_provider_url = format("https://cloud-provider-api-%s.grafana.net", data.grafana_cloud_stack.current.cluster_slug)
cloud_provider_access_token = grafana_cloud_access_policy_token.cloud_provider_token.token
}The Azure Credential Terraform model
The Cloud Provider portion of the Grafana Terraform provider enables configuring Azure metric collection through the following resources and data sources:
The following is a minimal Azure Credential resource definition:
resource "grafana_cloud_provider_azure_credential" "myazurecred" {
stack_id = <stack_id>
name = "my-credential"
client_id = "<client_id>"
client_secret = "<client_secret>"
tenant_id = "<tenant_id>"
}Full Terraform Example
The following snippet shows a full Terraform example that provisions an Azure service principal and uses it to collect Azure metrics:
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "~> 3.0"
}
azuread = {
source = "hashicorp/azuread"
version = "~> 2.0"
}
grafana = {
source = "grafana/grafana"
version = ">= 3.18.0"
}
}
}
variable "azure_subscription_id" {
type = string
description = "Azure Subscription ID source of the Azure metrics"
}
variable "org_slug" {
type = string
description = "Grafana Cloud Organization Slug where the Azure metrics will be collected"
}
variable "stack_slug" {
type = string
description = "Grafana Cloud Stack Slug where the Azure metrics will be collected"
}
variable "credential_name" {
type = string
description = "The name of the Azure Credential resource that will be created"
default = "azure-credential"
}
data "azurerm_client_config" "current" {}
resource "azuread_application" "grafana_cloud_azure_metrics" {
display_name = "grafana-cloud-azure-metrics"
}
resource "azuread_application_password" "grafana_cloud_azure_metrics" {
application_id = azuread_application.grafana_cloud_azure_metrics.client_id
end_date_relative = "8760h" # 1 year
}
resource "azurerm_role_assignment" "grafana_cloud_azure_metrics" {
scope = "/subscriptions/${var.azure_subscription_id}"
role_definition_name = "Monitoring Reader"
principal_id = azuread_application.grafana_cloud_azure_metrics.client_id
}
provider "grafana" {
}
data "grafana_cloud_organization" "current" {
slug = var.org_slug
}
data "grafana_cloud_stack" "current" {
slug = var.stack_slug
}
resource "grafana_cloud_access_policy" "cloud_provider_policy" {
region = data.grafana_cloud_stack.current.region_slug
name = "cloud-provider-terraform"
display_name = "Access policy used for Cloud Provider o11y setup"
scopes = ["integration-management:read", "integration-management:write", "stacks:read"]
realm {
type = "org"
identifier = data.grafana_cloud_organization.current.id
}
}
resource "grafana_cloud_access_policy_token" "cloud_provider_token" {
region = data.grafana_cloud_stack.current.region_slug
access_policy_id = grafana_cloud_access_policy.cloud_provider_policy.policy_id
name = "cloud-provider-terraform"
display_name = "Token used for Cloud Provider o11y setup"
}
provider "grafana" {
alias = "cloud_provider"
cloud_provider_url = format("https://cloud-provider-api-%s.grafana.net", data.grafana_cloud_stack.current.cluster_slug)
cloud_provider_access_token = grafana_cloud_access_policy_token.cloud_provider_token.token
}
resource "grafana_cloud_provider_azure_credential" "azurecred" {
provider = grafana.cloud_provider
stack_id = data.grafana_cloud_stack.current.id
name = var.credential_name
client_id = azuread_application.grafana_cloud_azure_metrics.client_id
client_secret = azuread_application_password.grafana_cloud_azure_metrics.value
tenant_id = data.azurerm_client_config.grafana_cloud_azure_metrics.tenant_id
}


