Monitoring #
Log memberitahu apa yang sudah terjadi. Monitoring memberitahu apa yang sedang terjadi — dan memperingatkan sebelum masalah menjadi insiden. Mengotomasi setup monitoring dengan Ansible memastikan setiap server langsung termonitor sejak pertama kali di-provision, dengan konfigurasi yang konsisten. Artikel ini membahas cara mendeploy stack monitoring Prometheus + Grafana menggunakan Ansible.
Instalasi Node Exporter #
Node Exporter adalah agen yang mengekspos metrik sistem (CPU, memory, disk, network) dalam format Prometheus:
# roles/node-exporter/tasks/main.yml
---
- name: Buat user node_exporter
user:
name: node_exporter
system: true
shell: /usr/sbin/nologin
home: /var/lib/node_exporter
create_home: false
- name: Download Node Exporter
get_url:
url: >
https://github.com/prometheus/node_exporter/releases/download/
v{{ node_exporter_version }}/node_exporter-{{ node_exporter_version }}.linux-amd64.tar.gz
dest: /tmp/node_exporter.tar.gz
checksum: "sha256:{{ node_exporter_checksum }}"
- name: Extract Node Exporter
unarchive:
src: /tmp/node_exporter.tar.gz
dest: /tmp/
remote_src: true
- name: Instal binary Node Exporter
copy:
src: "/tmp/node_exporter-{{ node_exporter_version }}.linux-amd64/node_exporter"
dest: /usr/local/bin/node_exporter
owner: root
group: root
mode: '0755'
remote_src: true
- name: Deploy systemd unit file
template:
src: node_exporter.service.j2
dest: /etc/systemd/system/node_exporter.service
notify:
- Reload systemd
- Restart node_exporter
- name: Jalankan Node Exporter
systemd:
name: node_exporter
state: started
enabled: true
Konfigurasi Prometheus #
Prometheus scrapes metrik dari semua target yang dikonfigurasi. Konfigurasi Prometheus bisa dibuat dinamis menggunakan template Jinja2 yang membaca inventory:
# roles/prometheus/tasks/main.yml
---
- name: Deploy konfigurasi Prometheus
template:
src: prometheus.yml.j2
dest: /etc/prometheus/prometheus.yml
owner: prometheus
group: prometheus
mode: '0644'
validate: promtool check config %s
notify: Reload Prometheus
{# roles/prometheus/templates/prometheus.yml.j2 #}
global:
scrape_interval: {{ prometheus_scrape_interval | default('15s') }}
evaluation_interval: {{ prometheus_evaluation_interval | default('15s') }}
external_labels:
cluster: {{ cluster_name }}
environment: {{ env }}
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager:9093
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
# Prometheus scraping itself
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
# Node Exporter dari semua server di inventory
- job_name: node_exporter
static_configs:
{% for host in groups['all'] %}
- targets: ['{{ hostvars[host]['ansible_default_ipv4']['address'] }}:9100']
labels:
hostname: {{ host }}
environment: {{ env }}
{% endfor %}
# Application metrics jika tersedia
- job_name: {{ app_name }}
static_configs:
{% for host in groups['appservers'] %}
- targets: ['{{ hostvars[host]['ansible_default_ipv4']['address'] }}:{{ app_metrics_port | default(9090) }}']
labels:
hostname: {{ host }}
{% endfor %}
metrics_path: /metrics
Alert Rules sebagai Kode #
Alert rules mendefinisikan kondisi yang memicu notifikasi. Menyimpannya sebagai file yang di-manage Ansible memastikan alert yang sama berlaku di semua lingkungan:
# roles/prometheus/tasks/alert-rules.yml
---
- name: Deploy alert rules
template:
src: "{{ item }}"
dest: "/etc/prometheus/rules/{{ item | basename | replace('.j2', '') }}"
owner: prometheus
mode: '0644'
with_fileglob:
- "templates/rules/*.j2"
notify: Reload Prometheus
# roles/prometheus/templates/rules/system.yml.j2
---
groups:
- name: system
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > {{ alert_cpu_threshold | default(85) }}
for: 5m
labels:
severity: warning
annotations:
summary: "CPU usage tinggi di {{ '{{' }} $labels.instance {{ '}}' }}"
description: "CPU usage {{ '{{' }} $value | humanizePercentage {{ '}}' }}"
- alert: LowDiskSpace
expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) < {{ alert_disk_threshold | default(0.15) }}
for: 5m
labels:
severity: critical
annotations:
summary: "Disk hampir penuh di {{ '{{' }} $labels.instance {{ '}}' }}"
description: "Disk tersisa {{ '{{' }} $value | humanizePercentage {{ '}}' }}"
- alert: HostDown
expr: up == 0
for: 2m
labels:
severity: critical
annotations:
summary: "Host tidak responsif: {{ '{{' }} $labels.instance {{ '}}' }}"
Setup Grafana #
# roles/grafana/tasks/main.yml
---
- name: Install Grafana
apt:
name: "grafana={{ grafana_version }}"
state: present
- name: Deploy konfigurasi Grafana
template:
src: grafana.ini.j2
dest: /etc/grafana/grafana.ini
owner: root
group: grafana
mode: '0640'
notify: Restart Grafana
- name: Provisioning datasource Prometheus
template:
src: datasource-prometheus.yml.j2
dest: /etc/grafana/provisioning/datasources/prometheus.yml
owner: root
group: grafana
mode: '0640'
notify: Restart Grafana
- name: Provisioning dashboard otomatis
copy:
src: "files/dashboards/{{ item }}"
dest: "/etc/grafana/provisioning/dashboards/{{ item }}"
owner: root
group: grafana
mode: '0640'
with_fileglob:
- "*.json"
notify: Restart Grafana
{# templates/datasource-prometheus.yml.j2 #}
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://{{ prometheus_host }}:9090
isDefault: true
editable: false
Ringkasan #
- Node Exporter di setiap managed node mengekspos metrik sistem — instal ini di semua server sebagai bagian dari role
common.- Template konfigurasi Prometheus menggunakan
hostvarsdangroupsuntuk otomatis menambahkan semua server di inventory sebagai scrape target — tidak perlu edit manual saat server baru ditambahkan.validate: promtool check config %suntuk memvalidasi konfigurasi Prometheus sebelum disimpan — konfigurasi yang salah bisa membuat Prometheus tidak mau reload.- Alert rules sebagai file template yang di-manage Ansible adalah monitoring as code — review di Git, konsisten di semua lingkungan, dan bisa di-rollback.
- Grafana provisioning via file YAML memungkinkan datasource dan dashboard dikonfigurasi otomatis saat Grafana di-restart — tidak perlu klik manual di UI.
- Selalu pin versi Prometheus, Node Exporter, dan Grafana — update yang tidak terkontrol bisa membreak dashboard atau mengubah format metrik.