This guide provides a complete Ansible playbook to install LibreNMS network monitoring with auto-discovery, MySQL database, and distributed polling.
Current LibreNMS version: 26.2.0
Create a file named librenms.yml:
---
- name: Install and Configure LibreNMS
hosts: librenms
become: true
vars:
librenms_version: "26.2.0"
librenms_port: 80
db_type: "mariadb"
db_name: "librenms"
db_user: "librenms"
db_password: "librenms_secure_password_123" # Change this!
db_root_password: "root_secure_password_456" # Change this!
librenms_admin_password: "librenms_admin_789" # Change this!
snmp_community: "public"
base_url: "http://{{ ansible_default_ipv4.address | default(ansible_host) }}"
tasks:
# =====================
# Prerequisites
# =====================
- name: Install prerequisites (Debian/Ubuntu)
apt:
name:
- nginx
- php-fpm
- php-mysql
- php-gd
- php-snmp
- php-curl
- php-mbstring
- php-json
- php-zip
- php-intl
- php-xml
- php-bcmath
- php-ldap
- mariadb-server
- mariadb-client
- snmp
- libsnmp-dev
- rrdtool
- fping
- git
- composer
- python3-pip
- python3-setuptools
- python3-virtualenv
- libapache2-mod-php
- whois
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install prerequisites (RHEL/CentOS)
yum:
name:
- nginx
- php-fpm
- php-mysqlnd
- php-gd
- php-snmp
- php-curl
- php-mbstring
- php-json
- php-zip
- php-intl
- php-xml
- php-bcmath
- php-ldap
- mariadb-server
- mariadb
- net-snmp
- net-snmp-utils
- rrdtool
- fping
- git
- composer
state: present
when: ansible_os_family == "RedHat"
- name: Install Python dependencies
pip:
name:
- python-memcached
- python3-memcached
state: present
when: ansible_os_family == "Debian"
# =====================
# Database Setup
# =====================
- name: Start and enable MariaDB
systemd:
name: "{{ 'mariadb' if ansible_os_family == 'Debian' else 'mariadb-server' }}"
enabled: true
state: started
- name: Set MariaDB root password
mysql_user:
name: root
password: "{{ db_root_password }}"
host_all: true
login_unix_socket: /var/run/mysqld/mysqld.sock
when: ansible_os_family == "Debian"
- name: Create LibreNMS database
mysql_db:
name: "{{ db_name }}"
encoding: utf8
collation: utf8_unicode_ci
login_unix_socket: /var/run/mysqld/mysqld.sock
login_user: root
login_password: "{{ db_root_password }}"
when: ansible_os_family == "Debian"
- name: Create LibreNMS database user
mysql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
priv: "{{ db_name }}.*:ALL"
host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
login_user: root
login_password: "{{ db_root_password }}"
when: ansible_os_family == "Debian"
# =====================
# LibreNMS Installation
# =====================
- name: Create LibreNMS user
user:
name: librenms
comment: "LibreNMS User"
home: /opt/librenms
create_home: true
shell: /bin/bash
- name: Clone LibreNMS repository
git:
repo: "https://github.com/librenms/librenms.git"
dest: /opt/librenms
version: master
update: true
become_user: librenms
- name: Set ownership for LibreNMS
file:
path: /opt/librenms
owner: librenms
group: librenms
recurse: true
- name: Copy LibreNMS environment file
copy:
src: /opt/librenms/.env.example
dest: /opt/librenms/.env
owner: librenms
group: librenms
mode: '0644'
remote_src: true
- name: Configure LibreNMS .env file
lineinfile:
path: /opt/librenms/.env
regexp: "^{{ item.key }}="
line: "{{ item.key }}={{ item.value }}"
loop:
- { key: 'APP_URL', value: '{{ base_url }}' }
- { key: 'DB_HOST', value: 'localhost' }
- { key: 'DB_DATABASE', value: '{{ db_name }}' }
- { key: 'DB_USERNAME', value: '{{ db_user }}' }
- { key: 'DB_PASSWORD', value: '{{ db_password }}' }
- name: Install Composer dependencies
command: composer install --no-dev --prefer-dist
args:
chdir: /opt/librenms
become_user: librenms
register: composer_result
changed_when: "'Installing dependencies' in composer_result.stdout"
- name: Create required directories
file:
path: "{{ item }}"
owner: librenms
group: librenms
mode: '0775'
state: directory
loop:
- /opt/librenms/logs
- /opt/librenms/storage
- /opt/librenms/bootstrap/cache
- /opt/librenms/rrd
- name: Run LibreNMS installation
command: ./lnms install
args:
chdir: /opt/librenms
become_user: librenms
environment:
APP_URL: "{{ base_url }}"
DB_HOST: localhost
DB_DATABASE: "{{ db_name }}"
DB_USERNAME: "{{ db_user }}"
DB_PASSWORD: "{{ db_password }}"
register: install_result
changed_when: "'LibreNMS installed successfully' in install_result.stdout"
- name: Create LibreNMS admin user
command: ./lnms user:add --admin --password="{{ librenms_admin_password }}" admin
args:
chdir: /opt/librenms
become_user: librenms
register: admin_create
changed_when: "'Created' in admin_create.stdout or 'already exists' in admin_create.stdout"
failed_when: false
# =====================
# Nginx Configuration
# =====================
- name: Create Nginx configuration for LibreNMS
copy:
dest: /etc/nginx/sites-available/librenms
owner: root
group: root
mode: '0644'
content: |
server {
listen 80;
server_name _;
root /opt/librenms/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
location ~ /\. {
deny all;
}
}
when: ansible_os_family == "Debian"
- name: Enable LibreNMS Nginx site (Debian/Ubuntu)
command: ln -sf /etc/nginx/sites-available/librenms /etc/nginx/sites-enabled/librenms
args:
creates: /etc/nginx/sites-enabled/librenms
when: ansible_os_family == "Debian"
notify: Restart Nginx
- name: Remove default Nginx site (Debian/Ubuntu)
file:
path: /etc/nginx/sites-enabled/default
state: absent
when: ansible_os_family == "Debian"
notify: Restart Nginx
- name: Create Nginx configuration for LibreNMS (RHEL)
copy:
dest: /etc/nginx/conf.d/librenms.conf
owner: root
group: root
mode: '0644'
content: |
server {
listen 80;
server_name _;
root /opt/librenms/html;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
when: ansible_os_family == "RedHat"
notify: Restart Nginx
# =====================
# PHP-FPM Configuration
# =====================
- name: Configure PHP-FPM for LibreNMS
lineinfile:
path: "/etc/php/{{ php_version }}/fpm/pool.d/www.conf"
regexp: "^{{ item.key }} ="
line: "{{ item.key }} = {{ item.value }}"
loop:
- { key: 'user', value: 'librenms' }
- { key: 'group', value: 'librenms' }
- { key: 'listen.owner', value: 'www-data' }
- { key: 'listen.group', value: 'www-data' }
- { key: 'pm', value: 'dynamic' }
- { key: 'pm.max_children', value: '50' }
- { key: 'pm.start_servers', value: '5' }
- { key: 'pm.min_spare_servers', value: '5' }
- { key: 'pm.max_spare_servers', value: '35' }
when: ansible_os_family == "Debian"
notify: Restart PHP-FPM
# =====================
# Cron Configuration
# =====================
- name: Create LibreNMS cron jobs
copy:
dest: /etc/cron.d/librenms
owner: root
group: root
mode: '0644'
content: |
# LibreNMS cron jobs
*/5 * * * * librenms /opt/librenms/discovery-wrapper.py -r 1 >> /dev/null 2>&1
*/5 * * * * librenms /opt/librenms/billing-wrapper.py >> /dev/null 2>&1
*/5 * * * * librenms /opt/librenms/check-services.py >> /dev/null 2>&1
*/5 * * * * librenms /opt/librenms/poller-wrapper.py -r 1 >> /dev/null 2>&1
33 */6 * * * librenms /opt/librenms/daily.sh >> /dev/null 2>&1
25 * * * * librenms /opt/librenms/alert-wrapper.py >> /dev/null 2>&1
@reboot librenms /opt/librenms/scripts/restart_services.sh
# =====================
# SNMP Configuration
# =====================
- name: Configure SNMP community
lineinfile:
path: /etc/snmp/snmp.conf
regexp: "^#?default"
line: "default {{ snmp_community }}"
failed_when: false
# =====================
# Firewall Configuration
# =====================
- name: Configure firewall (UFW)
ufw:
rule: allow
port: "{{ librenms_port }}"
proto: tcp
comment: "LibreNMS 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
# =====================
# Service Management
# =====================
- name: Enable and start Nginx
systemd:
name: nginx
enabled: true
state: started
- name: Enable and start PHP-FPM
systemd:
name: "{{ 'php' + php_version + '-fpm' if ansible_os_family == 'Debian' else 'php-fpm' }}"
enabled: true
state: started
- name: Wait for LibreNMS to be ready
wait_for:
port: "{{ librenms_port }}"
delay: 5
timeout: 120
- name: Display LibreNMS status
debug:
msg: |
LibreNMS {{ librenms_version }} installed successfully!
Web Interface: {{ base_url }}
Username: admin
Password: {{ librenms_admin_password }}
IMPORTANT: Change the default password after first login!
Run ./daily.sh for daily maintenance tasks.
handlers:
- name: Restart Nginx
systemd:
name: nginx
state: restarted
- name: Restart PHP-FPM
systemd:
name: "{{ 'php' + php_version + '-fpm' if ansible_os_family == 'Debian' else 'php-fpm' }}"
state: restarted
---
librenms:
hosts:
librenms-server:
ansible_host: 192.168.1.112
ansible_user: ansible
ansible_become: true
php_version: "8.2"
# Test connectivity
ansible all -i inventory.yml -m ping
# Run the LibreNMS playbook
ansible-playbook -i inventory.yml librenms.yml
# Run with custom passwords
ansible-playbook -i inventory.yml librenms.yml \
-e "db_password=MySecureDBPass123" \
-e "db_root_password=RootSecurePass456" \
-e "librenms_admin_password=AdminSecurePass789"
# Check Nginx status
ssh librenms-server "sudo systemctl status nginx"
# Check PHP-FPM status
ssh librenms-server "sudo systemctl status php8.2-fpm"
# Check LibreNMS validate
ssh librenms-server "sudo -u librenms php /opt/librenms/validate.php"
# Access web UI
# http://librenms-server
- name: Add devices to LibreNMS
hosts: librenms
become: true
become_user: librenms
vars:
librenms_dir: "/opt/librenms"
tasks:
- name: Add device via LibreNMS CLI
shell: |
./lnms device:add {{ item.ip }} --community=public --version=v2c
args:
chdir: "{{ librenms_dir }}"
loop: "{{ devices_to_monitor }}"
register: add_device_result
changed_when: "'Added' in add_device_result.stdout"
failed_when: false
- name: Run discovery on new devices
shell: |
./lnms device:discover {{ item.ip }}
args:
chdir: "{{ librenms_dir }}"
loop: "{{ devices_to_monitor }}"
register: discover_result
changed_when: "'Discovered' in discover_result.stdout"
failed_when: false
- name: Display device addition status
debug:
msg: "Added and discovered {{ devices_to_monitor | length }} devices in LibreNMS"
- name: Configure LibreNMS alerting
hosts: librenms
become: true
become_user: librenms
vars:
librenms_dir: "/opt/librenms"
alert_email: "admin@example.com"
slack_webhook: "https://hooks.slack.com/services/XXX/YYY/ZZZ"
tasks:
- name: Configure email alerts
shell: |
./lnms alert:channel:add email --name="Admin Email" --config='{"to": "{{ alert_email }}"}'
args:
chdir: "{{ librenms_dir }}"
register: email_result
changed_when: "'created' in email_result.stdout"
failed_when: false
- name: Configure Slack alerts
shell: |
./lnms alert:channel:add slack --name="Monitoring Slack" --config='{"url": "{{ slack_webhook }}", "channel": "#monitoring"}'
args:
chdir: "{{ librenms_dir }}"
register: slack_result
changed_when: "'created' in slack_result.stdout"
failed_when: false
- name: Display alert configuration status
debug:
msg: "Configured email and Slack alerting for LibreNMS"
# Check Nginx logs
sudo tail -f /var/log/nginx/error.log
# Check PHP-FPM logs
sudo tail -f /var/log/php8.2-fpm.log
# Run validation
sudo -u librenms php /opt/librenms/validate.php
# Check poller logs
sudo -u librenms tail -f /opt/librenms/logs/poller-wrapper.log
# Run poller manually
sudo -u librenms php /opt/librenms/poller-wrapper.php -r 1
# Check discovery logs
sudo -u librenms tail -f /opt/librenms/logs/discovery-wrapper.log
# Check database connection
mysql -u librenms -p -e "SELECT version();"
# Check database size
mysql -u librenms -p -e "SELECT table_schema, SUM(data_length + index_length) / 1024 / 1024 AS 'Size (MB)' FROM information_schema.tables WHERE table_schema = 'librenms' GROUP BY table_schema;"
We develop tailored automation solutions for:
Let’s discuss your requirements: office@linux-server-admin.com | Contact