Grafana Cloud plugin installation with Terraform

Hi, I am running into an issue where I am trying to install a plugin on Grafana Cloud through Terraform, and I am getting an error that says:

Error: the Cloud API client is required for this resource. Set the cloud_access_policy_token provider attribute

with grafana_cloud_plugin_installation.infinity_plugin,
on plugins.tf line 1, in resource “grafana_cloud_plugin_installation” “infinity_plugin”:
1: resource “grafana_cloud_plugin_installation” “infinity_plugin” {

The only other thing that I did was to upgrade the grafana provider version from 2.9.0 to 3.2.0, but I am not sure if this is the root cause of the issue because the version 3.0.0 of the [release notes](https://github.com/grafana/terraform-provider-grafana/releases/tag/v3.0.0) mentioned this:

Bump the Terraform provider to the latest v2 version, apply, then upgrade to v3 and remove/replace all the attributes that have been removed.

*Update: The issue is not related to the 2.9.0 to 3.2.1

Caution

Grafana Cloud Access Policies have replaced Grafana Cloud API keys. Use access policies and tokens instead of Cloud API keys.

I think you are using old API key for auth, so it is trying to force you to access policies.

Hi, thanks for helping me out! You were on to something! Someone had defined two different providers where one was using the auth attribute and another was using the cloud_access_policy_token attribute. I removed the provider that used the auth attribute and updated the other configuration files to use only one provider, but I am getting this error:

Error: the Grafana client is required for this resource. Set the auth and url provider attributes
  with grafana_data_source.infinity,
  on datasources.tf line 1, in resource "grafana_data_source" "infinity":
   1: resource "grafana_data_source" "infinity" {

Here’s the configuration:
providers.tf

terraform {
  required_version = ">= 1.8.2"
  required_providers {
    grafana = {
      source  = "grafana/grafana"
      version = ">= 3.2.1"
    }
  }
}

provider "grafana" {
  alias                                     = "cloud_stack"
  cloud_access_policy_token = var.cloud_access_policy_token
  # Adding url attribute here causes a Cycle Error and does not work
  # url                                      = grafana_cloud_stack.some_stack.url
}

main.tf

resource "grafana_cloud_stack" "some_stack" {
  provider = grafana.cloud_stack

  name        = "some-stack"
  description = "A dashboard of sorts"
  slug        = "some-stack"

  region_slug = "us"
}

resource "grafana_cloud_stack_service_account" "some_service_account" {
  provider = grafana.cloud_stack

  stack_slug = grafana_cloud_stack.some_stack.slug

  name        = "Some Service Account"
  role        = "Admin"
  is_disabled = false
}

resource "grafana_cloud_stack_service_account_token" "some_service_account_token" {
  provider = grafana.cloud_stack

  stack_slug         = grafana_cloud_stack.some_stack.slug
  service_account_id = grafana_cloud_stack_service_account.some_service_account.id

  name = "Some Service Account Token"
}

plugins.tf

resource "grafana_cloud_plugin_installation" "infinity_plugin" {
  provider = grafana.cloud_stack

  stack_slug = grafana_cloud_stack.some_stack.slug
  slug       = "yesoreyeram-infinity-datasource"
  version    = "2.8.0"
}

resource "grafana_cloud_plugin_installation" "business_charts_plugin" {
  provider = grafana.cloud_stack

  stack_slug = grafana_cloud_stack.some_stack.slug
  slug       = "volkovlabs-echarts-panel"
  version    = "6.1.0"
}

variables.tf

variable "cloud_access_policy_token" {
  description = "The access policy token for the Grafana Cloud account"
  type        = string
}

OMG :wink:

You didn’t provide reproducible example - datasources.tf is missing for example.

You need 2 providers:

  • “grafana cloud” provider (cloud_access_policy_token)
  • “grafana” provider (auth)

Then use right provider for right resource. E.g.

  • grafana_cloud_stack_service_account → “grafana cloud” provider
  • grafana_data_source → “grafana” provider

It looks like you are mixing resource with incorrect providers

1 Like

Thank you for the help! It works now! We were getting a Forbidden 403, but this was fixed when we added some permissions for stack-plugin. There’s a more complete version of the Terraform configuration we were using.

main.tf

resource "grafana_cloud_stack" "some_stack" {
  provider = grafana.cloud_stack

  name        = "some-stack"
  description = "A dashboard for the Common Operating Picture"
  slug        = "some-stack"

  region_slug = "us"
}

resource "grafana_cloud_stack_service_account" "some_service_account" {
  provider = grafana.cloud_stack

  stack_slug = grafana_cloud_stack.some_stack.slug

  name        = "Some Service Account"
  role        = "Admin"
  is_disabled = false
}

resource "grafana_cloud_stack_service_account_token" "some_service_account_token" {
  provider = grafana.cloud_stack

  stack_slug         = grafana_cloud_stack.some_stack.slug
  service_account_id = grafana_cloud_stack_service_account.some_service_account.id

  name = "Some Service Account Token"
}

backend.tf

terraform {
  backend "s3" {
    bucket         = "terraform-states"
    key            = "grafana/terraform.tfstate"
    dynamodb_table = "terraform-state-lock"
    region         = "us-west-2"
    encrypt        = true
  }
}

dashboards.tf

resource "grafana_dashboard" "some_dashboard" {
  provider = grafana.oss_with_auth

  folder = grafana_folder.dashboards.id

  config_json = file("./some_config.json")
}

datasources.tf

resource "grafana_data_source" "infinity" {
  provider = grafana.oss_with_auth

  type = "yesoreyeram-infinity-datasource"
  name = "Infinity Data Source"

  json_data_encoded = jsonencode({
    "allowedHosts" : [
      "https://google.com"
    ]
  })
}

folders.tf

resource "grafana_folder" "dashboards" {
  provider = grafana.oss_with_auth

  title = "Dashboards"
}

plugins.tf

resource "grafana_cloud_plugin_installation" "infinity_plugin" {
  provider = grafana.cloud_stack

  stack_slug = grafana_cloud_stack.some_stack.slug
  slug       = "yesoreyeram-infinity-datasource"
  version    = "2.8.0"
}

resource "grafana_cloud_plugin_installation" "business_charts_plugin" {
  provider = grafana.cloud_stack

  stack_slug = grafana_cloud_stack.some_stack.slug
  slug       = "volkovlabs-echarts-panel"
  version    = "6.1.0"
}

providers.tf

terraform {
  required_version = ">= 1.8.2"
  required_providers {
    grafana = {
      source  = "grafana/grafana"
      version = ">= 3.2.1"
    }
  }
}

provider "grafana" {
  alias                     = "cloud_stack"
  cloud_access_policy_token = var.cloud_access_policy_token
}

provider "grafana" {
  alias = "oss_with_auth"
  url   = grafana_cloud_stack.some_stack.url
  auth  = grafana_cloud_stack_service_account_token.some_service_account_token.key
}

variables.tf

variable "cloud_access_policy_token" {
  description = "The access policy token for the Grafana Cloud account"
  type        = string
}

some_config.json

{
  "annotations": {
    "list": [
      {
        "builtIn": 1,
        "datasource": {
          "type": "grafana",
          "uid": "-- Grafana --"
        },
        "enable": true,
        "hide": true,
        "iconColor": "rgba(0, 211, 255, 1)",
        "name": "Annotations & Alerts",
        "type": "dashboard"
      }
    ]
  },
  "editable": true,
  "fiscalYearStartMonth": 0,
  "graphTooltip": 0,
  "id": 19,
  "links": [],
  "panels": [],
  "schemaVersion": 39,
  "tags": [],
  "templating": {
    "list": []
  },
  "time": {
    "from": "now-6h",
    "to": "now"
  },
  "timepicker": {},
  "timezone": "browser",
  "title": "Some Dashboard",
  "uid": "adn7943nsgt8gf",
  "version": 16,
  "weekStart": ""
}
1 Like