How to manage your Grafana instance using Ansible

Pedro Gomes
2 min readFeb 22, 2022
  1. Create user for your Ansible playbook
  • Login as admin (the root user, not a user with admin role)
  • Create a user for your ansible playbook
  • Give it “Grafana Admin permissions” in `/admin/users/edit/:uid`

2. Create a sample playbook like

- name: Deploy user/team/folder/dashboard in Grafana for customer
hosts: localhost
gather_facts: False
connection: local
collections:
- community.grafana
vars:
grafana_url: https://metrics.enterprise.com
# user with "Grafana Admin" permissions
# requires login as admin to set it
grafana_user: ansible
grafana_pass: my-secure-password
grafana_team: gothamgrafana_users:
- name: Bruce Wayne
email: batman@gotham.city
login: batman
# Password update is not supported at the time
# generate random password (you can forward it to the user on the first run)
pass: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=32') }}"
- name: Bruce Wayne 4
email: batman4@gotham.city
login: bat4man
# Password update is not supported at the time
# generate random password (you can forward it to the user on the first run)
pass: "{{ lookup('password', '/dev/null chars=ascii_lowercase,digits length=32') }}"
tasks:

tasks:
- name: Create or update a Grafana user
community.grafana.grafana_user:
url: "{{ grafana_url }}"
# user method doesn't support API??
url_username: "{{ grafana_user }}"
url_password: "{{ grafana_pass }}"
name: "{{ item.name }}"
email: "{{ item.email }}"
login: "{{ item.login }}"
password: "{{ item.pass }}"
state: present
with_items: "{{ grafana_users }}"
register: changed_users

- name: Create a team with members and enforce the list of members
community.grafana.grafana_team:
grafana_url: "{{ grafana_url }}"
# grafana_api_key: "{{ key }}"
url_username: "{{ grafana_user }}"
url_password: "{{ grafana_pass }}"
name: "{{ grafana_team }}"
email: "{{ grafana_users | first | map(attribute='email') }}"
members: "{{ grafana_users | map(attribute='email') | list }}"
enforce_members: yes
state: present
register: team

- name: Create a folder
community.grafana.grafana_folder:
url: "{{ grafana_url }}"
grafana_api_key: "{{ key }}"
title: "{{ grafana_team }}"
state: present
register: folder

- name: Set folder permissions
uri:
url: "{{ grafana_url }}/api/folders/{{ folder.folder.uid }}/permissions"
method: POST
body: | # 1 - viewer | 2 - editor # teamId requires int here, otherwise returns 400
{"items": [{"role": "Editor", "permission": 2}, {"teamId": {{ team.team.id | int }}, "permission": 1}]}
body_format: json
return_content: yes
headers:
Authorization: "Bearer {{ key }}"
register: folder_perms

- name: Generate foo dashboard for customer X
template:
src: foo.json.j2
dest: /tmp/foo.json
# default {{ }} conflicts with grafana
variable_start_string: "{|"
variable_end_string: "|}"
register: template_changed

- name: Import Grafana dashboard
community.grafana.grafana_dashboard:
grafana_url: "{{ grafana_url }}"
grafana_api_key: "{{ key }}"
state: present
commit_message: Updated by ansible
overwrite: yes
path: /tmp/foo.json
folder: "gotham.city"
when: template_changed is changed

--

--