Since I spent some time today on this, I’d rather write it down. Creating a Prometheus datasource that uses Azure Authentication was not straight forward.

Here’s the end result:

- name: Create a datasource in Grafana
  hosts: localhost
  gather_facts: false
    - name: Create prometheus datasource
        name: prometheus_test
        ds_type: prometheus
        url: ""
        url_username: foo
        url_password: bar
        enforce_secure_data: true
            authType: clientsecret
            azureCloud: AzureCloud
            clientId: "{{ lookup('cloud.terraform.tf_output', 'clientid', project_path=playbook_dir + '../terraform/') }}"
            tenantId: "{{ lookup('cloud.terraform.tf_output', 'tenant_id', project_path=playbook_dir + '../terraform/') }}"
          azureClientSecret: "{{ lookup('cloud.terraform.tf_output', 'password', project_path=playbook_dir + '../terraform/') }}"

(Bonus: I lookup the client and tenant ID from Terraform state.)

How did I get to this? By creating the datasource by hand and then querying it via the Grafana API:

> curl -s '' | jq .
  "id": 7,
  "uid": "3E8CgP2Vk",
  "orgId": 1,
  "name": "Prometheus",
  "type": "prometheus",
  "typeLogoUrl": "",
  "access": "proxy",
  "url": "",
  "user": "",
  "database": "",
  "basicAuth": false,
  "withCredentials": false,
  "isDefault": false,
  "jsonData": {
    "azureCredentials": {
      "authType": "clientsecret",
      "azureCloud": "AzureCloud",
      "clientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    "httpMethod": "POST"
  "secureJsonFields": {
    "azureClientSecret": true,
    "basicAuthPassword": true
  "version": 10,
  "readOnly": false

There you get the jsonData and secureJsonFields. These are the special, required fields that you have to pass to Ansible to get exactly what you want.

Related posts: