D9.4 Grafana με Ansible 📈
Grafana Provisioning — Dashboards as code
Το Grafana υποστηρίζει provisioning — datasources και dashboards ορίζονται ως αρχεία (YAML/JSON) αντί για manual UI configuration.
Ρύθμιση provisioning
tasks:
# ── Provisioning directories ───────────────
- name: Grafana provisioning directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "472" # ← grafana UID
group: "472"
mode: '0755'
loop:
- /etc/grafana/provisioning/datasources
- /etc/grafana/provisioning/dashboards
- /var/lib/grafana/dashboards
# ── Datasource: Prometheus ─────────────────
- name: Prometheus datasource
ansible.builtin.copy:
dest: /etc/grafana/provisioning/datasources/prometheus.yml
owner: "472"
mode: '0644'
content: |
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
url: http://prometheus:9090
access: proxy
isDefault: true
editable: false # ← ΔΕΝ επιτρέπεται αλλαγή από UI
notify: Restart Grafana
# ── Dashboard provisioning ─────────────────
- name: Dashboard provisioning config
ansible.builtin.copy:
dest: /etc/grafana/provisioning/dashboards/default.yml
owner: "472"
mode: '0644'
content: |
apiVersion: 1
providers:
- name: Default
folder: ''
type: file
options:
path: /var/lib/grafana/dashboards
notify: Restart Grafana
# ── Dashboards JSON files ──────────────────
- name: Deploy dashboards
ansible.builtin.copy:
src: "files/grafana/dashboards/{{ item }}"
dest: /var/lib/grafana/dashboards/
owner: "472"
mode: '0644'
loop:
- node-exporter.json # ← Node Exporter Full dashboard
- docker-cadvisor.json # ← Docker container dashboard
- alerts-overview.json # ← Alert status dashboard
notify: Restart Grafana
Grafana container deployment
tasks:
- name: Grafana data volume
community.docker.docker_volume:
name: grafana_data
state: present
labels:
managed-by: ansible
- name: "📈 Grafana container"
community.docker.docker_container:
name: grafana
image: "grafana/grafana:10.3.0"
state: started
restart_policy: unless-stopped
user: "472:472" # ← grafana user
read_only: true
memory: "512m"
cap_drop: [ALL]
security_opts: ["no-new-privileges:true"]
tmpfs:
/tmp: "size=64m"
ports:
- "127.0.0.1:3000:3000" # ← localhost only
env:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: "{{ vault_grafana_pass }}"
GF_SECURITY_DISABLE_GRAVATAR: "true"
GF_ANALYTICS_REPORTING_ENABLED: "false"
GF_ANALYTICS_CHECK_FOR_UPDATES: "false"
GF_USERS_ALLOW_SIGN_UP: "false"
GF_AUTH_ANONYMOUS_ENABLED: "false"
GF_SERVER_ROOT_URL: "https://monitoring.{{ app_domain }}"
GF_SMTP_ENABLED: "true"
GF_SMTP_HOST: "{{ smtp_host }}:587"
GF_SMTP_USER: "{{ smtp_user }}"
GF_SMTP_PASSWORD: "{{ vault_smtp_pass }}"
GF_SMTP_FROM_ADDRESS: "grafana@{{ app_domain }}"
volumes:
- "grafana_data:/var/lib/grafana:rw"
- "/etc/grafana/provisioning:/etc/grafana/provisioning:ro"
- "/var/lib/grafana/dashboards:/var/lib/grafana/dashboards:ro"
networks:
- name: monitoring_net
labels:
monitoring: grafana
managed-by: ansible
no_log: true
handlers:
- name: Restart Grafana
community.docker.docker_container:
name: grafana
state: started
restart: true
Grafana API — Programmatic management
tasks:
# ── Αναμονή για Grafana ────────────────────
- name: Wait for Grafana
ansible.builtin.uri:
url: "http://localhost:3000/api/health"
status_code: 200
retries: 12
delay: 5
until: not grafana_health.failed
register: grafana_health
# ── Δημιουργία API key ─────────────────────
- name: Create API key
ansible.builtin.uri:
url: "http://localhost:3000/api/auth/keys"
method: POST
user: admin
password: "{{ vault_grafana_pass }}"
force_basic_auth: true
body_format: json
body:
name: ansible-provisioning
role: Admin
status_code: [200, 409] # 409 = already exists
return_content: true
register: api_key
no_log: true
# ── Δημιουργία organization ───────────────
- name: Set org name
ansible.builtin.uri:
url: "http://localhost:3000/api/org"
method: PUT
headers:
Authorization: "Bearer {{ api_key.json.key | default('') }}"
body_format: json
body:
name: "{{ company_name | default('My Company') }}"
when: api_key.json.key is defined
no_log: true
Σύνοψη D9.4
Grafana
│
├── Provisioning (as code):
│ ├── datasources/ → Prometheus (auto-configured)
│ └── dashboards/ → JSON files (auto-loaded)
│
├── Container:
│ ├── user: 472 (grafana non-root)
│ ├── read_only: true
│ └── port: 127.0.0.1:3000
│
├── Security settings (env vars):
│ ├── allow_sign_up: false
│ ├── anonymous: disabled
│ └── SMTP για notifications
│
└── API: REST API για programmatic management