Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for dashboard inputs #329

Open
gbolo opened this issue Nov 14, 2023 · 2 comments
Open

add support for dashboard inputs #329

gbolo opened this issue Nov 14, 2023 · 2 comments

Comments

@gbolo
Copy link

gbolo commented Nov 14, 2023

SUMMARY

Currently, the web UI in Grafana supports providing inputs when importing dashboards. for example, a dashboard json may have a body containing:

...
  "__inputs": [
    {
      "name": "DS_PROMETHEUS",
      "label": "Prometheus",
      "description": "",
      "type": "datasource",
      "pluginId": "prometheus",
      "pluginName": "Prometheus"
    }
  ]
...

In the same body it can reference those inputs like: "datasource": "${DS_PROMETHEUS}".

When using the web UI in Grafana, it interprets these inputs and allows you to fill them in with a drop down menu. Then when it makes the POST /api/dashboards/import call, it will have the values for those inputs in the body like:

...
  "inputs": [
    {
      "name": "DS_PROMETHEUS",
      "type": "datasource",
      "pluginId": "prometheus",
      "value": "2bc3bb07-e974-5690-9826-c71ae0fdb03a"
    }
  ]
...
ISSUE TYPE
  • add a parameter to the community.grafana.grafana_dashboard module to support supplying the input part of the request body.
COMPONENT NAME

community.grafana.grafana_dashboard

ADDITIONAL INFORMATION

For example, see this dashboard: https://grafana.com/grafana/dashboards/405-node-exporter-server-metrics/

@kosssi
Copy link

kosssi commented Sep 17, 2024

Dashboard import is not functional without this feature. Did you manage to tie a dashboard to Prometheus otherwise @gbolo ?

@pbdname
Copy link

pbdname commented Sep 25, 2024

@kosssi, I've come up with an (overly complicated) workaround, but it's the only way I'm able to set up/update the dashboard. Also, I'm really new into Prometheus and Grafana, so I might be missing some concepts, but still, it works for my use case.

The following tasks import Prometheus datasource and then sets up a dashboard for Blackbox Exporter (uid: xtkCtBkiz, see the grafana_dashboard_uid variable), which is defined in template dashboard.json.j2. This template is not directly downloaded from Grafana.com, but I've first imported it manually in one Grafana instance and then copied the JSON Model into the Jinja2 template.

main.yml:

- name: Update Prometheus datasource in Grafana
  community.grafana.grafana_datasource:
    grafana_url: "https://{{ prometheus_grafana_domain }}"
    grafana_user: "admin"
    grafana_password: "{{ vaulted_grafana_user_passwords['admin'] }}"
    name: prometheus
    ds_type: prometheus
    ds_url: http://prometheus:9090/
    access: proxy
  register: grafana_prometheus_datasource
  changed_when: false   # https://github.com/ansible-collections/community.grafana/issues/127
  tags: grafana

- name: Update Grafana dashboards
  ansible.builtin.include_tasks: grafana-dashboard.yml
  loop:
    - {
      uid: blackbox-exporter-j4da,
      # The template has to have 'uid' in all 'datasource' replaced by '{{ datasource_uid }}', for example:
      #   ...
      #   "datasource": {
      #     "type": "prometheus",
      #     "uid": "{{ datasource_uid }}"
      #   }
      #   ...
      template: grafana-dashboards/blackbox-exporter-j4da.json.j2,
      datasource_uid: "{{ grafana_prometheus_datasource.datasource.uid }}"
    }
    - {
      uid: fcb1bdc8-fa9d-4bfd-b725-003b174473ad,
      template: grafana-dashboards/fcb1bdc8-fa9d-4bfd-b725-003b174473ad.json.j2,
      datasource_uid: "{{ grafana_prometheus_datasource.datasource.uid }}"
    }
    - {
      uid: xtkCtBkis,
      template: grafana-dashboards/xtkCtBkis.json.j2,
      datasource_uid: "{{ grafana_prometheus_datasource.datasource.uid }}"
    }
    - {
      uid: xtkCtBkiz,
      template: grafana-dashboards/xtkCtBkiz.json.j2,
      datasource_uid: "{{ grafana_prometheus_datasource.datasource.uid }}"
    }
  loop_control:
    loop_var: dashboard
  tags: grafana

grafana-dashboard.yml:

---

- name: Get current dashboard configuration
  block:
    - name: Create a temporary file for current dashboard JSON
      ansible.builtin.tempfile:
        state: file
        suffix: .dashboard-current.json
      register: temp_dashboard_json_current_file
      changed_when: false
      tags: grafana

    - name: Export current dashboard
      community.grafana.grafana_dashboard:
        grafana_url: "https://{{ prometheus_grafana_domain }}"
        grafana_user: "admin"
        grafana_password: "{{ vaulted_grafana_user_passwords['admin'] }}"
        state: export
        uid: "{{ dashboard.uid }}"
        path: "{{ temp_dashboard_json_current_file.path }}"
      register: grafana_dashboard_current_uid
      changed_when: false
      when: not ansible_check_mode
      tags: grafana

    - name: Read the current dashboard into variable
      ansible.builtin.set_fact:
        dashboard_json_current: "{{ lookup('file', temp_dashboard_json_current_file.path) | from_json }}"
      when:
        - grafana_dashboard_current_uid.msg is defined
        - not (grafana_dashboard_current_uid.msg is search("does not exist."))
      tags: grafana
    - name: Remove the 'id' key from current dashboard
      ansible.builtin.set_fact:
        dashboard_json_current_without_id: "{{ dashboard_json_current.dashboard | combine({'id': omit}, recursive=True) }}"
      when:
        - grafana_dashboard_current_uid.msg is defined
        - not (grafana_dashboard_current_uid.msg is search("does not exist."))
      tags: grafana

- name: Prepare new dashboard configuration
  block:
    - name: Create a temporary file for new dashboard JSON
      ansible.builtin.tempfile:
        state: file
        suffix: .dashboard-new.json
      register: temp_dashboard_json_new_file
      changed_when: false
      tags: grafana

    - name: Generate dashboard JSON with correct datasource UID
      ansible.builtin.template:
        src: "{{ dashboard.template }}"
        dest: "{{ temp_dashboard_json_new_file.path }}"
        owner: root
        group: root
        mode: "600"
      vars:
        datasource_uid: "{{ dashboard.datasource_uid }}"
      changed_when: false
      when: not ansible_check_mode
      tags: grafana

    - name: Read the new dashboard
      ansible.builtin.set_fact:
        dashboard_json_new: "{{ lookup('file', temp_dashboard_json_new_file.path) | from_json }}"
      when: dashboard_json_current_without_id is defined
      tags: grafana

    - name: Remove the 'id' key from new dashboard
      ansible.builtin.set_fact:
        dashboard_json_new_without_id: "{{ dashboard_json_new | combine({'id': omit}, recursive=True) }}"
      when: dashboard_json_current_without_id is defined
      tags: grafana

- name: Remove current dashboard from Grafana
  community.grafana.grafana_dashboard:
    grafana_url: "https://{{ prometheus_grafana_domain }}"
    grafana_user: "admin"
    grafana_password: "{{ vaulted_grafana_user_passwords['admin'] }}"
    uid: "{{ dashboard.uid }}"
    state: absent
  when:
    - dashboard_json_current_without_id is defined
    - dashboard_json_current_without_id != dashboard_json_new_without_id
  tags: grafana

- name: Import Blackbox Exporter dashboard to Grafana
  community.grafana.grafana_dashboard:
    grafana_url: "https://{{ prometheus_grafana_domain }}"
    grafana_user: "admin"
    grafana_password: "{{ vaulted_grafana_user_passwords['admin'] }}"
    state: present
    commit_message: Updated by Ansible
    path: "{{ temp_dashboard_json_new_file.path }}"
  when:
    - dashboard_json_current_without_id is not defined or dashboard_json_current_without_id != dashboard_json_new_without_id
    - temp_dashboard_json_new_file.path is defined
  tags: grafana

- name: Clean up temporary files
  ansible.builtin.file:
    path: "{{ item }}"
    state: absent
  loop:
    - "{{ temp_dashboard_json_new_file.path }}"
    - "{{ temp_dashboard_json_current_file.path }}"
  changed_when: false
  when: not ansible_check_mode
  tags: grafana

...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants