This guide provides a complete Ansible playbook to install Munin monitoring server and deploy Munin nodes to monitored hosts.
Current Munin version: 2.0.75
Create a file named munin.yml:
---
- name: Install and Configure Munin Server
hosts: munin_server
become: true
vars:
munin_port: 80
munin_admin_user: "admin"
munin_admin_password: "munin_admin_123" # Change this!
munin_contact_email: "admin@example.com"
tasks:
- name: Install Munin server (Debian/Ubuntu)
apt:
name:
- munin
- munin-plugins-core
- munin-plugins-extra
- munin-doc
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install Munin server (RHEL/CentOS)
yum:
name:
- munin
state: present
when: ansible_os_family == "RedHat"
- name: Install Apache web server (Debian/Ubuntu)
apt:
name:
- apache2
- libcgi-fast-perl
state: present
when: ansible_os_family == "Debian"
- name: Install Apache web server (RHEL/CentOS)
yum:
name:
- httpd
- perl-CGI
state: present
when: ansible_os_family == "RedHat"
- name: Configure Munin main configuration
lineinfile:
path: /etc/munin/munin.conf
regexp: "^{{ item.key }} "
line: "{{ item.key }} {{ item.value }}"
loop:
- { key: 'dbdir', value: '/var/lib/munin' }
- { key: 'htmldir', value: '/var/cache/munin/www' }
- { key: 'logdir', value: '/var/log/munin' }
- { key: 'rundir', value: '/var/run/munin' }
- { key: 'tmpldir', value: '/etc/munin/templates' }
- { key: 'includedir', value: '/etc/munin/munin-conf.d' }
- { key: 'contact.admin.command', value: 'mail -s "Munin notification" {{ munin_contact_email }}' }
- { key: 'contact.admin.always_send', value: 'critical' }
- name: Configure Munin CGI
lineinfile:
path: /etc/munin/munin.conf
regexp: "^#?html_strategy"
line: "html_strategy cgi"
- name: Enable Apache rewrite module (Debian/Ubuntu)
apache2_module:
name: rewrite
state: present
when: ansible_os_family == "Debian"
- name: Enable Apache CGI module (Debian/Ubuntu)
apache2_module:
name: cgi
state: present
when: ansible_os_family == "Debian"
- name: Restart Apache (Debian/Ubuntu)
systemd:
name: apache2
enabled: true
state: restarted
when: ansible_os_family == "Debian"
- name: Restart httpd (RHEL/CentOS)
systemd:
name: httpd
enabled: true
state: restarted
when: ansible_os_family == "RedHat"
- name: Create Munin admin htpasswd file
htpasswd:
path: /etc/munin/htpasswd
name: "{{ munin_admin_user }}"
password: "{{ munin_admin_password }}"
owner: root
group: www-data
mode: '0640'
when: ansible_os_family == "Debian"
- name: Create Munin admin htpasswd file (RHEL)
htpasswd:
path: /etc/munin/htpasswd
name: "{{ munin_admin_user }}"
password: "{{ munin_admin_password }}"
owner: root
group: apache
mode: '0640'
when: ansible_os_family == "RedHat"
- name: Configure Apache for Munin (Debian/Ubuntu)
copy:
dest: /etc/apache2/conf-available/munin.conf
owner: root
group: root
mode: '0644'
content: |
Alias /munin /var/cache/munin/www
<Directory /var/cache/munin/www>
Options +FollowSymLinks +SymLinksIfOwnerMatch
AllowOverride None
Require all granted
# Basic authentication
AuthType Basic
AuthName "Munin"
AuthUserFile /etc/munin/htpasswd
Require valid-user
</Directory>
ScriptAlias /munin-cgi/munin-cgi-graph /usr/lib/munin/cgi/munin-cgi-graph
<Location /munin-cgi/munin-cgi-graph>
Require all granted
</Location>
when: ansible_os_family == "Debian"
notify: Restart Apache
- name: Enable Munin Apache configuration (Debian/Ubuntu)
command: a2enconf munin
args:
creates: /etc/apache2/conf-enabled/munin.conf
when: ansible_os_family == "Debian"
notify: Restart Apache
- name: Configure firewall (UFW)
ufw:
rule: allow
port: "{{ munin_port }}"
proto: tcp
comment: "Munin web interface"
when: ansible_os_family == "Debian"
failed_when: false
- name: Configure firewall (firewalld)
firewalld:
service: http
permanent: true
immediate: true
state: enabled
when: ansible_os_family == "RedHat"
failed_when: false
- name: Run Munin cron job manually for initial data
cron:
name: "munin"
job: "/usr/bin/munin-cron"
state: present
register: munin_cron
- name: Execute Munin cron immediately
command: /usr/bin/munin-cron
changed_when: false
- name: Wait for initial graphs to be generated
wait_for:
path: /var/cache/munin/www/index.html
delay: 10
timeout: 120
- name: Display Munin status
debug:
msg: |
Munin installed successfully!
Web Interface: http://{{ ansible_default_ipv4.address | default(ansible_host) }}/munin
Username: {{ munin_admin_user }}
Password: {{ munin_admin_password }}
Munin will collect data every 5 minutes.
Initial graphs will appear after first data collection.
handlers:
- name: Restart Apache
systemd:
name: "{{ 'apache2' if ansible_os_family == 'Debian' else 'httpd' }}"
state: restarted
- name: Deploy Munin Node to monitored hosts
hosts: monitored_hosts
become: true
vars:
munin_server_ip: "192.168.1.109"
munin_node_port: 4949
tasks:
- name: Install Munin node (Debian/Ubuntu)
apt:
name:
- munin-node
- munin-plugins-core
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install Munin node (RHEL/CentOS)
yum:
name:
- munin-node
state: present
when: ansible_os_family == "RedHat"
- name: Configure Munin node to allow server
lineinfile:
path: /etc/munin/munin-node.conf
regexp: "^allow"
line: "allow {{ munin_server_ip }}"
insertafter: "^# allow"
- name: Configure Munin node hostname
lineinfile:
path: /etc/munin/munin-node.conf
regexp: "^host_name"
line: "host_name {{ ansible_fqdn | default(ansible_hostname) }}"
- name: Enable and start Munin node
systemd:
name: munin-node
enabled: true
state: started
- name: Configure firewall for Munin node
ufw:
rule: allow
port: "{{ munin_node_port }}"
proto: tcp
comment: "Munin node"
when: ansible_os_family == "Debian"
failed_when: false
- name: Test Munin node connection from server
delegate_to: "{{ munin_server_ip }}"
command: "telnet {{ ansible_host }} {{ munin_node_port }}"
register: telnet_result
failed_when: false
changed_when: false
- name: Add hosts to Munin server configuration
hosts: munin_server
become: true
vars:
munin_server_ip: "192.168.1.109"
tasks:
- name: Create Munin host configurations
copy:
dest: "/etc/munin/munin-conf.d/{{ item }}.conf"
owner: root
group: root
mode: '0644'
content: |
[{{ item }}]
address {{ item }}
use_node_name yes
loop: "{{ munin_nodes }}"
- name: Reload Munin configuration
systemd:
name: munin
state: reloaded
- name: Run Munin cron to update graphs
command: /usr/bin/munin-cron
changed_when: false
- name: Configure Munin plugins
hosts: munin_server
become: true
tasks:
- name: Enable additional Munin plugins
file:
src: "/usr/share/munin/plugins/{{ item }}"
dest: "/etc/munin/plugins/{{ item }}"
state: link
loop:
- apache_accesses
- mysql_queries
- nginx_request
- postfix_mailqueue
failed_when: false
- name: Configure MySQL plugin
copy:
dest: /etc/munin/plugin-conf.d/mysql
owner: root
group: root
mode: '0644'
content: |
[mysql_*]
env.mysqluser root
env.mysqlpassword {{ mysql_password | default('') }}
when: mysql_password is defined
- name: Restart Munin node on all hosts
systemd:
name: munin-node
state: restarted
delegate_to: "{{ item }}"
loop: "{{ munin_nodes }}"
failed_when: false
---
munin_server:
hosts:
munin:
ansible_host: 192.168.1.109
ansible_user: ansible
ansible_become: true
monitored_hosts:
hosts:
web1:
ansible_host: 192.168.1.10
web2:
ansible_host: 192.168.1.11
db1:
ansible_host: 192.168.1.20
# Install Munin server
ansible-playbook -i inventory.yml munin.yml
# Deploy Munin nodes
ansible-playbook -i inventory.yml munin-nodes.yml
# Add hosts to Munin
ansible-playbook -i inventory.yml munin-add-hosts.yml \
-e "munin_nodes=['192.168.1.10', '192.168.1.11', '192.168.1.20']"
# Check Munin service status
ssh munin "sudo systemctl status munin"
# Check Munin node status
ssh munin "sudo systemctl status munin-node"
# Test Munin node connection
telnet munin-node 4949
# Access web UI
# http://munin/munin
# Check Munin logs
sudo tail -f /var/log/munin/munin-update.log
# Run Munin cron manually
sudo /usr/bin/munin-cron
# Check if data is being collected
ls -la /var/lib/munin/
# Test connection from server
telnet node-ip 4949
# Check node configuration
sudo cat /etc/munin/munin-node.conf
# Check node logs
sudo tail -f /var/log/munin/munin-node.log
# List available plugins
ls -la /usr/share/munin/plugins/
# List enabled plugins
ls -la /etc/munin/plugins/
# Test a plugin
sudo /usr/share/munin/plugins/if_eth1
Beyond this playbook, we offer:
Contact our automation team: office@linux-server-admin.com