This guide provides a complete Ansible playbook to install Monit from official packages with proper configuration for process monitoring, service management, and alerting.
Current Monit version: 5.33.0 (varies by distribution)
Create a file named monit.yml:
---
- name: Install and Configure Monit
hosts: monit
become: true
vars:
monit_config_dir: "/etc/monit"
monit_log_file: "/var/log/monit.log"
monit_mail_server: "" # Optional: SMTP server for alerts
monit_admin_email: "" # Optional: Admin email for alerts
tasks:
- name: Install Monit (Debian/Ubuntu)
apt:
name: monit
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install EPEL repository (RHEL/CentOS)
yum:
name: epel-release
state: present
when: ansible_os_family == "RedHat"
- name: Install Monit (RHEL/CentOS)
yum:
name: monit
state: present
when: ansible_os_family == "RedHat"
- name: Create Monit configuration directory
file:
path: "{{ monit_config_dir }}/conf.d"
state: directory
owner: root
group: root
mode: '0750'
- name: Configure Monit main settings
lineinfile:
path: "{{ monit_config_dir }}/monitrc"
regexp: "^#?\s*{{ item.key }}"
line: "{{ item.key }} {{ item.value }}"
loop:
- { key: 'set daemon', value: '60' }
- { key: 'set logfile', value: monit.log }
- { key: 'set syslog', value: '' }
validate: 'monit -t -c %s'
- name: Configure Monit HTTP interface
lineinfile:
path: "{{ monit_config_dir }}/monitrc"
regexp: "^#?\s*set httpd port"
line: "set httpd port 2812 and use the admin:monit123 allow admin:monit123"
validate: 'monit -t -c %s'
- name: Configure mail server (optional)
lineinfile:
path: "{{ monit_config_dir }}/monitrc"
regexp: "^#?\s*set mailserver"
line: "set mailserver {{ monit_mail_server }} username {{ monit_mail_user | default('') }} password {{ monit_mail_password | default('') }}"
when: monit_mail_server | length > 0
validate: 'monit -t -c %s'
- name: Configure alert email (optional)
lineinfile:
path: "{{ monit_config_dir }}/monitrc"
regexp: "^#?\s*set alert"
line: "set alert {{ monit_admin_email }}"
when: monit_admin_email | length > 0
validate: 'monit -t -c %s'
- name: Include conf.d configurations
lineinfile:
path: "{{ monit_config_dir }}/monitrc"
regexp: "^#?\s*include"
line: "include {{ monit_config_dir }}/conf.d/*"
validate: 'monit -t -c %s'
- name: Set proper permissions on monitrc
file:
path: "{{ monit_config_dir }}/monitrc"
owner: root
group: root
mode: '0700'
- name: Enable and start Monit service
systemd:
name: monit
enabled: true
state: started
daemon_reload: true
- name: Configure firewall (UFW)
ufw:
rule: allow
port: 2812
proto: tcp
comment: "Monit web interface"
when: ansible_os_family == "Debian"
failed_when: false
- name: Configure firewall (firewalld)
firewalld:
port: 2812/tcp
permanent: true
immediate: true
state: enabled
when: ansible_os_family == "RedHat"
failed_when: false
- name: Verify Monit configuration
command: monit -t
register: monit_test
changed_when: false
failed_when: monit_test.rc != 0
- name: Display Monit status
debug:
msg: |
Monit installed successfully!
Web Interface: http://{{ ansible_default_ipv4.address | default(ansible_host) }}:2812
Username: admin
Password: monit123
IMPORTANT: Change the default password after first login!
Configuration directory: {{ monit_config_dir }}
---
monit:
hosts:
monit-server:
ansible_host: 192.168.1.110
ansible_user: ansible
ansible_become: true
# Test connectivity
ansible all -i inventory.yml -m ping
# Run the Monit playbook
ansible-playbook -i inventory.yml monit.yml
# Run with custom credentials
ansible-playbook -i inventory.yml monit.yml \
-e "monit_admin_email=admin@example.com" \
-e "monit_mail_server=smtp.example.com"
# Check service status
ssh monit-server "sudo systemctl status monit"
# Test configuration
ssh monit-server "sudo monit -t"
# View Monit status
ssh monit-server "sudo monit status"
# Access web UI
# http://monit-server:2812
- name: Configure Monit to monitor services
hosts: monit
become: true
tasks:
- name: Monitor Nginx
copy:
dest: "{{ monit_config_dir }}/conf.d/nginx.conf"
owner: root
group: root
mode: '0640'
content: |
check process nginx with pidfile /run/nginx.pid
start program = "/usr/sbin/service nginx start"
stop program = "/usr/sbin/service nginx stop"
if failed host 127.0.0.1 port 80 protocol http
and request "/" with timeout 5 seconds then restart
if cpu > 80% for 5 cycles then restart
if totalmem > 500 MB for 5 cycles then restart
if 3 restarts within 5 cycles then timeout
alert admin@example.com only on { timeout, nonexist }
- name: Monitor MySQL
copy:
dest: "{{ monit_config_dir }}/conf.d/mysql.conf"
owner: root
group: root
mode: '0640'
content: |
check process mysql with pidfile /run/mysqld/mysqld.pid
start program = "/usr/sbin/service mysql start"
stop program = "/usr/sbin/service mysql stop"
if failed host 127.0.0.1 port 3306 protocol mysql then restart
if cpu > 80% for 5 cycles then restart
if totalmem > 1 GB for 5 cycles then restart
if 3 restarts within 5 cycles then timeout
- name: Monitor PostgreSQL
copy:
dest: "{{ monit_config_dir }}/conf.d/postgresql.conf"
owner: root
group: root
mode: '0640'
content: |
check process postgresql with pidfile /run/postgresql/*.pid
start program = "/usr/sbin/service postgresql start"
stop program = "/usr/sbin/service postgresql stop"
if failed host 127.0.0.1 port 5432 protocol postgresql then restart
if cpu > 80% for 5 cycles then restart
if totalmem > 1 GB for 5 cycles then restart
- name: Monitor Redis
copy:
dest: "{{ monit_config_dir }}/conf.d/redis.conf"
owner: root
group: root
mode: '0640'
content: |
check process redis with pidfile /run/redis/redis-server.pid
start program = "/usr/sbin/service redis-server start"
stop program = "/usr/sbin/service redis-server stop"
if failed host 127.0.0.1 port 6379 protocol redis then restart
if cpu > 60% for 5 cycles then restart
if totalmem > 500 MB for 5 cycles then restart
- name: Reload Monit to apply configurations
systemd:
name: monit
state: reloaded
- name: Configure Monit system monitoring
hosts: monit
become: true
tasks:
- name: Monitor system filesystem
copy:
dest: "{{ monit_config_dir }}/conf.d/filesystem.conf"
owner: root
group: root
mode: '0640'
content: |
check filesystem rootfs with path /dev/sda1
if space > 90% then alert
if space > 95% then exec "/usr/local/bin/cleanup.sh"
if inode usage > 90% then alert
- name: Monitor system memory
copy:
dest: "{{ monit_config_dir }}/conf.d/memory.conf"
owner: root
group: root
mode: '0640'
content: |
check system $HOST
if loadavg (1min) > 4 then alert
if loadavg (5min) > 2 then alert
if memory usage > 90% then alert
if swap usage > 50% then alert
if cpu usage (user) > 80% then alert
- name: Monitor network interface
copy:
dest: "{{ monit_config_dir }}/conf.d/network.conf"
owner: root
group: root
mode: '0640'
content: |
check network eth0 with interface eth0
if failed ping 8.8.8.8 then alert
if link status then alert
if download > 100 MB/s then alert
if upload > 100 MB/s then alert
- name: Reload Monit
systemd:
name: monit
state: reloaded
- name: Configure Monit for custom applications
hosts: monit
become: true
vars:
app_name: "myapp"
app_pidfile: "/var/run/myapp/myapp.pid"
app_port: 8080
tasks:
- name: Monitor custom application
copy:
dest: "{{ monit_config_dir }}/conf.d/{{ app_name }}.conf"
owner: root
group: root
mode: '0640'
content: |
check process {{ app_name }} with pidfile {{ app_pidfile }}
start program = "/usr/bin/systemctl start {{ app_name }}"
stop program = "/usr/bin/systemctl stop {{ app_name }}"
if failed host 127.0.0.1 port {{ app_port }} then restart
if cpu > 80% for 5 cycles then restart
if totalmem > 1 GB for 5 cycles then restart
if 5 restarts within 10 cycles then timeout
alert admin@example.com only on { timeout, nonexist }
- name: Monitor application log file
copy:
dest: "{{ monit_config_dir }}/conf.d/{{ app_name }}-log.conf"
owner: root
group: root
mode: '0640'
content: |
check file {{ app_name }}_log with path /var/log/{{ app_name }}/{{ app_name }}.log
if size > 100 MB then rotate
if match "ERROR|CRITICAL|FATAL" then alert
- name: Reload Monit
systemd:
name: monit
state: reloaded
- name: Configure Monit email alerts
hosts: monit
become: true
vars:
smtp_server: "smtp.example.com"
smtp_port: 587
smtp_user: "monit@example.com"
smtp_password: "smtp_password"
alert_email: "admin@example.com"
tasks:
- name: Configure SMTP settings
lineinfile:
path: "{{ monit_config_dir }}/monitrc"
regexp: "^#?\s*set mailserver"
line: "set mailserver {{ smtp_server }} port {{ smtp_port }} username {{ smtp_user }} password '{{ smtp_password }} using TLSV1"
validate: 'monit -t -c %s'
- name: Set alert email
lineinfile:
path: "{{ monit_config_dir }}/monitrc"
regexp: "^#?\s*set alert"
line: "set alert {{ alert_email }}"
validate: 'monit -t -c %s'
- name: Configure mail format
blockinfile:
path: "{{ monit_config_dir }}/monitrc"
marker: "# {mark} MAIL FORMAT"
block: |
set mail-format {
from: monit@{{ ansible_fqdn }}
subject: "Monit Alert: $SERVICE $EVENT at $DATE"
message: "Monit detected $ACTION on $HOST at $DATE.\n\nService: $SERVICE\nEvent: $EVENT\nDescription: $DESCRIPTION\n\n-- \nMonit Monitoring System"
}
validate: 'monit -t -c %s'
- name: Restart Monit
systemd:
name: monit
state: restarted
# Check Monit logs
sudo tail -f /var/log/monit.log
# Check systemd logs
sudo journalctl -u monit -f
# Test configuration
sudo monit -t
# Validate configuration
sudo monit -t -c /etc/monit/monitrc
# Check syntax of specific config
sudo monit -t -c /etc/monit/conf.d/nginx.conf
# Test mail configuration
sudo monit -v
# Check mail logs
sudo tail -f /var/log/mail.log
# Check if port is listening
sudo netstat -tlnp | grep 2812
# Test locally
curl http://localhost:2812
# Check firewall
sudo ufw status | grep 2812
We develop tailored automation solutions for:
Let’s discuss your requirements: office@linux-server-admin.com | Contact