Full Automation of Nagios Monitoring Setup with Ansible

Full Automation of Nagios Monitoring Setup with Ansible

In this guide, we’ll walk you through the full automation of Nagios monitoring setup using Ansible, from installing Nagios on your servers to configuring remote client monitoring. Setting up and managing an IT infrastructure monitoring system can be a time-consuming and error-prone task, especially when done manually. Fortunately, by leveraging the power of Nagios and Ansible, you can fully automate the process, saving time and reducing human errors. Nagios is a widely-used, open-source monitoring tool that keeps track of your servers, applications, and services to ensure optimal performance. Ansible, a powerful automation framework, makes it easy to configure and manage complex infrastructures with simple, repeatable scripts.

Full Automation of Nagios Monitoring Setup with Ansible

Whether you’re a system administrator, DevOps engineer, or IT professional, this tutorial will provide you with the tools you need to automate Nagios setup and improve your infrastructure management.

Deployment Environment Nodes

In this guide, we have multiple nodes for various purposes. See the table below;

Linux DistributionNode IP AddressNode Role
Ubuntu 24.04 LTS192.168.122.185Ansible Control Plane
Ubuntu 24.04 LTS192.168.122.127Nagios Core Server
CentOS Stream 9192.168.122.11Nagios Core Server
Debian GNU/Linux 12192.168.122.152Nagios NRPE Agent
Fedora Linux 40192.168.122.110Nagios NRPE Agent
Ubuntu 24.04 LTS192.168.122.79Nagios NRPE Agent
Ubuntu 22.04 LTS192.168.122.174Nagios NRPE Agent

Install Ansible on Linux

Install Ansible on your control node. A control node is the machine where Ansible is installed and from which all the automation tasks are executed.

We are using Ubuntu 24.04 LTS server as our Ansible control plane. Thus, to install Ansible on Ubuntu 24.04, proceed as follows;

Run system update;

sudo apt update

Install and upgrade PIP3

sudo apt install python3-pip -y

Create Ansible virtual environment. A virtual environment allows you to isolate the dependencies required by Ansible from the rest of the system. This ensures that the specific versions of Python libraries and modules needed for Ansible to function properly are separated from other applications on your machine.

sudo apt install python3-venv
python3 -m venv ansible

Activate Ansible Python’s virtual environment and install PIP3;

source ansible/bin/activate
python3 -m pip install --upgrade pip

Install Ansible;

python3 -m pip install ansible

Enable Ansible auto-completion;

python3 -m pip install argcomplete

Confirm the Ansible version;

ansible --version
ansible [core 2.17.6]
  config file = /home/kifarunix/nagios-ansible/ansible.cfg
  configured module search path = ['/home/kifarunix/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/kifarunix/ansible/lib/python3.12/site-packages/ansible
  ansible collection location = /home/kifarunix/.ansible/collections:/usr/share/ansible/collections
  executable location = /home/kifarunix/ansible/bin/ansible
  python version = 3.12.3 (main, Nov  6 2024, 18:32:19) [GCC 13.2.0] (/home/kifarunix/ansible/bin/python3)
  jinja version = 3.1.4
  libyaml = True

Create Ansible User on Managed Nodes

Ansible uses the user you are logged in on control node as to connect to all remote devices. If the user doesn’t exists on the remote hosts, you need to create the account.

So, on all Ansible remotely managed hosts, create an account with sudo rights. This is the only manual task you might need to do at the beggining, -:).

Replace the user, kifarunix, below with your username.

On Debian based systems;

sudo useradd -G sudo -s /bin/bash -m kifarunix

On RHEL based systems;

sudo useradd -G wheel -s /bin/bash -m kifarunix

Set the account password;

sudo passwd kifarunix

Setup Ansible SSH Keys

When using Ansible, you have two options for authenticating with remote systems:

  • SSH keys or
  • Password Authentication

SSH keys authentication is more preferred as a method of connection and is considered more secure and convenient compared to password authentication.

Therefore, on the Ansible control node, you need to generate a public and private SSH key pair. Once you have the keys, copy the public key to the remote system’s authorized keys file.

Thus, as a non root user, on the control node, run the command below to generate SSH key pair. It is recommended to use SSH keys with a passphrase for increased security.

ssh-keygen

If you used a different path other than the default one to store SSH key pair, then in Ansible configuration file, you can define custom path to SSH key using the private_key_file option.

Copy Ansible SSH Public Key to Managed Nodes

Once you have the SSH key pair generated, proceed to copy the key to the user accounts you will use on managed nodes for Ansible deployment tasks;

(We are using the name, kifarunix, in this guide. Replace the username accordingly)

for i in 127 11 152 110 79 174; do ssh-copy-id [email protected].$i; done

If you are using non default SSH key file, specify the path to the key using the -i option;

for i in 127 11 152 110 79 174; do ssh-copy-id -i <custom-ssh-key-path> [email protected].$i; done

Create Ansible Configuration Directory/Files

/etc/ansible is a default Ansible directory. If you install Ansible via PIP, chances are, default configuration for Ansible is not created.

You can use your custom directory for Ansible configuration. Ansible will search for the configuration file  in the following order:

  • ANSIBLE_CONFIG (environment variable if set)
  • ansible.cfg (in the current directory)
  • ~/.ansible.cfg (in the home directory)
  • /etc/ansible/ansible.cfg

We will use a custom configuration directory to easily control Ansible.

mkdir ~/nagios-ansible

We have created our custom Ansible configuration file, ansible.cfg under the custom directory created above.

cat ~/nagios-ansible/ansible.cfg
[defaults]
remote_user = kifarunix
interpreter_python = auto_silent
roles_path = /home/kifarunix/nagios-ansible/roles 

[privilege_escalation]
become = true
become_method = sudo

You can update your Ansible configuration as you see fit!

Prepare Nagios-Ansible Deployment Directory Structure

This is how we setup our Nagios Ansible deployment directory structure.

tree ~/nagios-ansible/
/home/kifarunix/nagios-ansible/
├── ansible.cfg
├── nagios-inventory
│   └── hosts
├── roles
│   ├── clean
│   │   ├── tasks
│   │   │   └── main.yaml
│   │   └── vars
│   │       └── main.yaml
│   ├── nagios-nrpe-agents
│   │   ├── tasks
│   │   │   └── main.yaml
│   │   ├── templates
│   │   │   ├── check_memory
│   │   │   └── nrpe.cfg.j2
│   │   └── vars
│   │       ├── Debian.yaml
│   │       ├── main.yaml
│   │       └── RedHat.yaml
│   └── nagios-server
│       ├── tasks
│       │   ├── main.yaml
│       ├── templates
│       │   ├── commands.cfg.j2
│       │   ├── contacts.cfg.j2
│       │   ├── host-metrics.cfg.j2
│       │   ├── hosts-n-groups.cfg.j2
│       │   ├── htdigest.users.j2
│       │   ├── nagios4-cgi.conf.j2
│       │   ├── nagios.conf.j2
│       │   └── template.cfg.j2
│       └── vars
│           ├── Debian.yaml
│           ├── main.yaml
│           └── RedHat.yaml
└── site.yaml

14 directories, 24 files

Create Ansible Nagios Hosts Inventory File

The inventory file contains a list of hosts and groups of hosts that are managed by Ansible. By default, inventory file is set to /etc/ansible/hosts. You can specify a different inventory file using the -i option or using the inventory option in the configuration file.

We set out inventory file to /home/kifarunix/nagios-ansible/nagios-inventory/hosts in the configuration above;

So, let’s navigate to our parent directory, /home/kifarunix/nagios-ansible.

cd /home/kifarunix/nagios-ansible

Sample Inventory;

[all:vars]
ansible_become_pass = 'password'

[nagios-server]
192.168.122.127
192.168.122.11

[nagios-nrpe-agents]
192.168.122.152 hostname=web01.kifarunix.com alias="Kifarunix Web Server 01 Node" group=web
192.168.122.110 hostname=mongo.kifarunix.com alias="Kifarunix MongoDB Node" group=web
192.168.122.79 hostname=ctrl01.kifarunix.com alias="Kifarunix Controller Node" group=crownjewels
192.168.122.174 hostname=titan.kifarunix.com alias="Kifarunix Titan Node" group=crownjewels

As you can see, we defined our password for escalating privileges on the hosts fine. If you want, you can use more secure methods!

We have also added more attributes to the agents hosts including hostnames, alias that will be used in host definitions, and their logical groups.

Breakdown of Ansible Nagios Deployment Roles

As you can see, we have multiple roles for our Nagios deployment. Roles define how different tasks related to the Nagios deployment will be executed. In Ansible, roles allow you to encapsulate specific functionality into reusable, modular pieces. Here, we see three main roles:

  • clean,
  • nagios-nrpe-agents
  • nagios-server

clean Role

This role contains tasks to clean up existing Nagios installations or configuration files before starting a new deployment. Cleaning is an essential part of deployment to ensure that previous configurations or installations do not interfere with the new setup.

  • tasks/main.yaml: Contains the tasks to be executed when the clean role is invoked. These tasks could include removing old Nagios packages or configuration files.
  • vars/main.yaml: Variables used by the clean role. These might include things like paths to files that need to be deleted or packages that need to be uninstalled.

Main clean task

cat roles/clean/tasks/main.yaml
---
- include_vars:
    file: "{{ item }}"
  loop:
    - "{{ '../../nagios-server/vars/' + ansible_os_family + '.yaml'}}"
    - "{{ '../../nagios-nrpe-agents/vars/' + ansible_os_family + '.yaml' }}"

- name: Uninstall Nagios and Nagios plugins
  block:
    - name: Uninstall Nagios in Debian systems
      apt:
        name:
          - nagios4
          - monitoring-plugins
          - nagios-nrpe-plugin
        state: absent
        autoremove: yes
        purge: true
      when: ansible_os_family == 'Debian'

    - name: Uninstall Nagios in RHEL systems
      yum:
        name:
          - nagios
          - nagios-plugins
          - nagios-plugins-nrpe
        state: absent
        autoremove: true
      when: ansible_os_family == 'RedHat'
 
- name: Remove Nagios configs dir if it has custom configs
  file:
    path: "{{ item }}"
    state: absent
  loop:
    - "{{ nagios_parent_config_dir }}"
    - "{{ apache_parent_config_dir }}"

- name: Un-Install NRPE Agents and Nagios Plugins
  block:
    - name: Un-Install NRPE on Debian systems
      apt:
        name:
          - nagios-nrpe-server
          - nagios-plugins
        state: absent
        autoremove: yes
      when: ansible_os_family == 'Debian'

    - name: Install NRPE on RedHat systems
      yum:
        name:
          - nrpe
          - nagios-plugins-load
          - nagios-plugins-http
          - nagios-plugins-users
          - nagios-plugins-procs
          - nagios-plugins-disk
          - nagios-plugins-swap
          - nagios-plugins-nrpe
          - nagios-plugins-uptime            
        state: absent
        autoremove: true
      when: ansible_os_family == 'RedHat'

    - name: Remove NRPE configs dir if it has custom configs
      file:
        path: "{{ nrpe_configs_dir }}"
        state: absent

Variables;

cat roles/clean/vars/main.yaml
nrpe_configs_dir: /etc/nagios

nagios-nrpe-agents/ Role

This role is responsible for installing and configuring the Nagios Remote Plugin Executor (NRPE) agents on monitored hosts. NRPE allows Nagios to execute checks remotely on the client systems, such as CPU load, disk usage, memory usage, etc.

  • tasks/main.yaml: Contains tasks for installing and configuring the NRPE agent on the managed hosts.
  • templates/nrpe.cfg.j2: This is a Jinja2 template used to generate the NRPE configuration file on the client machines. The template will be populated with variables defined in the vars directory.
  • vars/: The vars subdirectory contains different YAML files for various operating systems (e.g., Debian.yaml, RedHat.yaml) that define the specific configurations or packages needed for different OS distributions.

Main installation task

cat roles/nagios-nrpe-agents/tasks/main.yaml
---
- include_vars: '{{ ansible_os_family }}.yaml'

- name: Install NRPE Agents and Nagios Plugins
  block:
    - name: Install NRPE and Nagios plugins on Debian/Ubuntu
      apt:
        name:
          - nagios-nrpe-server
          - nagios-plugins
        state: present
        update_cache: yes
      when: ansible_os_family == 'Debian'

    - name: Install NRPE and Nagios plugins on CentOS/RedHat/Rocky
      yum:
        name:
          - nrpe
          - bc
          - nagios-plugins-load
          - nagios-plugins-http
          - nagios-plugins-users
          - nagios-plugins-procs
          - nagios-plugins-disk
          - nagios-plugins-swap
          - nagios-plugins-nrpe
          - nagios-plugins-uptime            
          - vim
        state: present
      when: ansible_os_family == 'RedHat'

- name: Configure NRPE Agent
  block:
    - name: Configure NRPE Agent using template
      template:
        src: nrpe.cfg.j2
        dest: "{{ nrpe_agent_config }}"
    
    - name: Copy check_memory script
      copy:
        src: ../templates/check_memory
        dest: "{{ plugins_path }}/"
        mode: '0755'

- name: Disable NRPE Checks via SSL (depends on your nrpe commands definition)
  block:
    - name: Disble NRPE SSL Support on Debian
      lineinfile:
        path: "{{ nrpe_env_file }}"
        regexp: '^#NRPE_OPTS="-n"'
        line: 'NRPE_OPTS="-n"'
      when: ansible_os_family == 'Debian'
        
    - name: Disble NRPE SSL Support on RHEL
      lineinfile:
        path: "{{ nrpe_env_file }}"
        regexp: '^NRPE_SSL_OPT=""'
        line: 'NRPE_SSL_OPT="-n"'
      when: ansible_os_family == 'RedHat'

- name: Restart NRPE service
  systemd_service:
    name: "{{ nrpe_service }}"
    daemon_reload: true
    state: restarted
    enabled: true

NRPE configuration template

cat roles/nagios-nrpe-agents/templates/nrpe.cfg.j2
log_facility=daemon
server_port=5666
nrpe_user=nagios
nrpe_group=nagios
allowed_hosts=127.0.0.1,{{ groups['nagios-server'] | join(',') }}
dont_blame_nrpe=1
debug=0
command_timeout=60
connection_timeout=300
command[check_disk]={{ plugins_path }}/check_disk -w {{ disk_warn }} -c {{ disk_crit }} -p {{ disk_part }}
command[check_users]={{ plugins_path }}/check_users -w {{ user_warn }} -c {{ user_crit }}
command[check_load]={{ plugins_path }}/check_load -w {{ lw_value }},{{ lw_value }},{{ lw_value }} -c {{ lc_value }},{{ lc_value }},{{ lc_value }}
command[check_procs]={{ plugins_path }}/check_procs -w {{ procs_warn }} -c {{ procs_crit }}
command[check_memory]={{ plugins_path }}/check_memory -w {{ mem_warn }} -c {{ mem_crit }}
command[check_swap]={{ plugins_path }}/check_swap -w {{ disk_warn }} -c {{ disk_crit }}
command[check_zombie_procs]={{ plugins_path }}/check_procs -w {{ z_procs_warn }} -c {{ z_procs_crit }} -s Z

Custom Script to check RAM usage;

cat roles/nagios-nrpe-agents/templates/check_memory
#!/bin/bash

if [ "$1" = "-w" ] && [ "$2" -gt "0" ] && [ "$3" = "-c" ] && [ "$4" -gt "0" ]; then
    FreeM=`free -m`
    memTotal_m=`echo "$FreeM" |grep Mem |awk '{print $2}'`
    memUsed_m=`echo "$FreeM" |grep Mem |awk '{print $3}'`
    memFree_m=`echo "$FreeM" |grep Mem |awk '{print $4}'`
    memBuffer_m=`echo "$FreeM" |grep Mem |awk '{print $6}'`
    memCache_m=`echo "$FreeM" |grep Mem |awk '{print $7}'`
    memUsedPrc=`echo $((($memUsed_m*100)/$memTotal_m))||cut -d. -f1`
    if [ "$memUsedPrc" -ge "$4" ]; then
        echo "Memory: CRITICAL Total: $memTotal_m MB - Used: $memUsed_m MB - $memUsedPrc% used!|TOTAL=$memTotal_m MB;; USED=$memUsed_m MB;; FREE=$memFree_m MB;; CACHE=$memCache_m MB;; BUFFER=$memBuffer_m MB;;"
        exit 2
    elif [ "$memUsedPrc" -ge "$2" ]; then
        echo "Memory: WARNING Total: $memTotal_m MB - Used: $memUsed_m MB - $memUsedPrc% used!|TOTAL=$memTotal_m MB;; USED=$memUsed_m MB;; FREE=$memFree_m MB;; CACHE=$memCache_m MB;; BUFFER=$memBuffer_m MB;;"
        exit 1
    else
        echo "Memory: OK Total: $memTotal_m MB - Used: $memUsed_m MB - $memUsedPrc% used|TOTAL=$memTotal_m MB;; USED=$memUsed_m MB;; FREE=$memFree_m MB;; CACHE=$memCache_m MB;; BUFFER=$memBuffer_m MB;;"
        exit 0
    fi
else    # If inputs are not as expected, print help.
    sName="`echo $0|awk -F '/' '{print $NF}'`"
    echo -e "\n\n\t\t### $sName Version 2.0###\n"
    echo -e "# Usage:\t$sName -w  -c "
    echo -e "\t\t= warnlevel and critlevel is percentage value without %\n"
    echo "# EXAMPLE:\t/usr/lib64/nagios/plugins/$sName -w 80 -c 90"
    echo -e "\n"
    exit
fi

Variables used:

cat roles/nagios-nrpe-agents/vars/Debian.yaml
plugins_path: /usr/lib/nagios/plugins
nrpe_env_file: /etc/default/nagios-nrpe-server  
nrpe_service: nagios-nrpe-server
nrpe_plugins_dir: /etc/nagios-plugins
cat roles/nagios-nrpe-agents/vars/main.yaml
nrpe_agent_config: /etc/nagios/nrpe.cfg
lw_value: "{{ (ansible_processor_count | int * 80 / 100) | int }}"
lc_value: "{{ (ansible_processor_count | int * 70 / 100) | int }}"
disk_warn: "20%"
disk_crit: "10%"
disk_part: /
user_warn: 5
user_crit: 10
procs_warn: 1000
procs_crit: 1500
mem_warn: 80
mem_crit: 90
z_procs_warn: 5
z_procs_crit: 10
roles/nagios-nrpe-agents/vars/RedHat.yaml
plugins_path: /usr/lib64/nagios/plugins
nrpe_env_file: /etc/sysconfig/nrpe
nrpe_service: nrpe

nagios-server/ Role

This role is responsible for setting up the Nagios monitoring server itself. It involves tasks like installing Nagios, configuring Nagios settings, setting up Nagios web access, and defining host and service checks for monitoring.

  • tasks/main.yaml: The main tasks for setting up Nagios, such as installing the Nagios software, configuring Nagios service files, and ensuring Nagios is running.
  • templates/: Contains various Jinja2 template files used to generate Nagios configuration files. These templates help create custom Nagios configurations based on the inventory or variable data. For example;
    • nagios.conf.j2 is a template that will generate the main Nagios configuration file, while commands.cfg.j2 could define various monitoring commands used by Nagios to perform checks.
    • htdigest.users.j2 might define authentication configurations for Nagios web access, ensuring that users are authenticated before accessing the Nagios interface.
  • vars/: Similar to nagios-nrpe-agents, this directory contains operating system-specific variable files. The main.yaml file might contain default settings that are applicable across systems, while the Debian.yaml and RedHat.yaml files contain OS-specific configurations for the Nagios server.

Main task:

cat roles/nagios-server/tasks/main.yaml
---
- include_vars: '{{ ansible_os_family }}.yaml'

- name: Install Nagios4 and Monitoring Plugins on Debian-based systems
  apt:
    name:
      - nagios4
      - monitoring-plugins
      - nagios-nrpe-plugin
    state: present
    update_cache: yes
  when: ansible_os_family == 'Debian' 
- name: Install Nagios4 and Monitoring Plugins on RHEL-based systems
  yum:
    name:
      - nagios
      - nagios-plugins
      - nagios-plugins-nrpe
    state: present
    update_cache: yes
  when: ansible_os_family == 'RedHat'

- name: Create Apache Nagios Configuration file
  block:
    - name: Apache-Nagios Config for Debian
      template:
        src: "nagios4-cgi.conf.j2"
        dest: "{{ apache_nagios_config }}"
      when: ansible_os_family == 'Debian'

    - name: Apache-Nagios Config for Redhat
      template:
        src: "nagios.conf.j2"
        dest: "{{ apache_nagios_config }}"
      when: ansible_os_family == 'RedHat'

- name: Enable Apache rewrite, cgi, auth_digest, authz_groupfile modules
  apache2_module:
    name: "{{ item.module }}"
    state: "{{ item.state }}"
  loop:
    - { module: rewrite, state: present }
    - { module: cgi, state: present }
    - { module: auth_digest, state: present }
    - { module: authz_groupfile, state: present }
  when: ansible_os_family == 'Debian'

- name: Configure Nagios Authentication users
  block:
    - name: Add users to auth file on Debian
      template:
        src: "htdigest.users.j2"
        dest: "{{ auth_file }}"
      when: ansible_os_family == 'Debian'

    - name: Ensure the htpasswd file exists
      file:
        path: "{{ auth_file }}"
        state: touch
        mode: '0640'
      when: ansible_os_family == 'RedHat'

    - name: Add users to auth file on RHEL
      command: "htpasswd -b {{ auth_file}} {{ item.username }} {{ item.password }}"
      with_items: "{{ nagios_users }}"
      when: ansible_os_family == 'RedHat' and item.username is defined and item.password is defined

- name: Enable Nagios authentication
  block:
    - name: Enable authentication
      lineinfile:
        path: "{{ nagios_cgi_config }}"
        regexp: "^use_authentication=0$"
        line: "use_authentication=1"
        backup: yes

    - name: Get list of Nagios admin users
      set_fact:
        admin_user_list: "{{ nagios_users | selectattr('role','equalto','admin') | map(attribute='username') | join(',') }}"
        readonly_user_list: "{{ nagios_users | selectattr('role','equalto','readonly') | map(attribute='username') | join(',') }}"

    - name: Check if the admin user_list is already in the Nagios config file
      command: "grep -q '{{ admin_user_list }}' {{ nagios_cgi_config }}"
      register: grep_admin_result
      failed_when: false
      changed_when: false

    - name: Check if the readonly user list is already in the Nagios config file
      command: "grep -q '{{ readonly_user_list }}' {{ nagios_cgi_config }}"
      register: grep_readonly_result
      failed_when: false
      changed_when: false

    - name: Define admins users
      replace:
        path: "{{ nagios_cgi_config }}"
        regexp: 'nagiosadmin'
        replace: "{{ admin_user_list }}"
      when: grep_admin_result.rc != 0

    - name: Define read-only users
      lineinfile:
        path: "{{ nagios_cgi_config }}"
        regexp: "^#authorized_for_read_only="
        line: "authorized_for_read_only={{ readonly_user_list }}"
      when: grep_readonly_result.rc != 0

    - name: Set Results Display Limit to 0
      lineinfile:
        path: "{{ nagios_cgi_config }}"
        regexp: "^result_limit=100$"
        line: "result_limit=0"

    - name: Create Nagios custom configs directory
      file:
        path: "{{ nagios_custom_configs_dir }}"
        state: directory

    - name: Add Nagios Custom Configurations Directory
      lineinfile:
        path:  "{{ nagios_main_config }}"
        line: "cfg_dir={{ nagios_custom_configs_dir }}"
        insertbefore: '^# OBJECT CACHE FILE'
      when: nagios_custom_configs_dir is defined

- name: Install Nagios Custom configurations
  block:
    - name: Ensure the Nagios custom configs directory exists
      file:
        path: "{{ nagios_custom_configs_dir }}"
        state: directory

    - name: Install Check commands configuration
      template:
        src: "commands.cfg.j2"
        dest: "{{ nagios_custom_configs_dir }}/commands.cfg"

    - name: Install Nagios Contacts configuration
      template:
        src: "contacts.cfg.j2"
        dest: "{{ nagios_custom_configs_dir }}/contacts.cfg"
    - name: Install Nagios Hosts and Services Definition Template
      template:
        src: "template.cfg.j2"
        dest: "{{ nagios_custom_configs_dir }}/template.cfg"

    - name: Define Nagios Hosts and Host Groups
      template:
        src: "hosts-n-groups.cfg.j2"
        dest: "{{ nagios_custom_configs_dir }}/hosts-n-groups.cfg"

    - name: Create Service Definition
      template:
        src: "host-metrics.cfg.j2"
        dest: "{{ nagios_custom_configs_dir }}/host-metrics.cfg"
#
- name: (Re)Start and enable Nagios and Apache
  block:
    - name: Check Nagios Syntax
      command: "{{ nagios_bin }} -v {{ nagios_main_config }}"
      register: nagios_syntax_check
      changed_when: false

    - name: Show some info if Nagios syntax check fail
      fail:
        msg: "Nagios configuration syntax check failed. Login to server and check"
      when: nagios_syntax_check.rc != 0

    - name: Check Apache Syntax
      command: "{{ apache_bin }} -t"
      register: apache_syntax_check
      changed_when: false

    - name: Show some info if Apache syntax check fail
      fail:
        msg: "Apache configuration syntax check failed. Login to server and check"
      when: apache_syntax_check.rc != 0

    - name: (Re)start Nagios
      service:
        name: "{{ nagios_service }}"
        state: restarted
        enabled: yes
      when: nagios_syntax_check.rc == 0

    - name: (Re)start Apache
      service:
        name: "{{ apache_service }}"
        state: restarted
        enabled: yes
      when: apache_syntax_check.rc == 0

Nagios Checks Command Template:

cat roles/nagios-server/templates/commands.cfg.j2
define command {
    command_name           {{ command_name }}
    command_line           {{ nagios_plugins_dir }}/check_nrpe -2 -n -H $HOSTADDRESS$ -c $ARG1$
}

Contacts Template;

cat roles/nagios-server/templates/contacts.cfg.j2
# CONTACT  
define contact {
        contact_name                    {{ contact_name }}
        alias                           {{ contact_alias }}
        service_notification_period     24x7
        host_notification_period        24x7
        service_notification_options    w,u,c,r
        host_notification_options       d,u,r
        service_notification_commands   notify-service-by-email
        host_notification_commands      notify-host-by-email
	email				{{ email }}
}
#
# CONTACT GROUP
#
define contactgroup {
        contactgroup_name       {{ contact_group_name }}
        alias                   {{ contact_group_alias }}
        members                 {{ contact_name }}
}

Host Resource Metrics to check RAM, CPU, Processes…template

cat roles/nagios-server/templates/host-metrics.cfg.j2
# Service Definitions
{% set services = {
    'check_disk': 'Resource Disk Usage',
    'check_load': 'Resource CPU Load',
    'check_users': 'Resource Logged in Users',
    'check_swap': 'Resource Swap Usage',
    'check_memory': 'Resource RAM Usage',
    'check_procs': 'Resource Running Processes'
} %}

{% for service, description in services.items() %}
define service {
    use				{{ svc_template }}          
    hostgroup_name              {{ general_group_name }}
    service_description         {{ description }}
    check_command               {{ command_name }}!{{ service }}
}
{% endfor %}

Hosts and Groups template;

cat roles/nagios-server/templates/hosts-n-groups.cfg.j2
# HOSTS DEFINITION
{% for host in groups['nagios-nrpe-agents'] %}
define host {
  use             {{ host_template }}
  host_name       {{ hostvars[host].hostname }}
  alias           {{ hostvars[host].alias }}
  address	  {{ host }}
}
{% endfor %}
# General Hostgroup
define hostgroup {
    hostgroup_name      {{ general_group_name }}
    alias               {{ general_group_name }}
    members             {% for member in groups['nagios-nrpe-agents'] %}{{ hostvars[member].hostname }}{% if not loop.last %},{% endif %}{% endfor %}

}

{% set unique_groups = [] %}
{% for host in groups['nagios-nrpe-agents'] %}
{% set group = hostvars[host].group %}
{% if group is not in unique_groups %}
{% set unique_groups = unique_groups.append(group) %}
{% endif %}
{% endfor %}

{% for group in unique_groups %}
define hostgroup {
    hostgroup_name  {{ group }}
    alias           {{ group }}
    members         {% for member in groups['nagios-nrpe-agents'] %}{% if hostvars[member].group == group %}{{ hostvars[member].hostname }}{% if not loop.last %},{% endif %}{% endif %}{% endfor %}

}
{% endfor %}

Nagios Authentication Users template;

cat roles/nagios-server/templates/htdigest.users.j2
{% for user in nagios_users %}
{{ user.username }}:{{ realm }}:{{ user.password }}
{% endfor %}

Nagios Apache configuration template for Debian systems;

cat roles/nagios-server/templates/nagios4-cgi.conf.j2
<ScriptAlias /cgi-bin/nagios4 /usr/lib/cgi-bin/nagios4>
<ScriptAlias /nagios4/cgi-bin /usr/lib/cgi-bin/nagios4>

<Alias /nagios4/stylesheets /etc/nagios4/stylesheets>

<Alias /nagios4 /usr/share/nagios4/htdocs>

<DirectoryMatch (/usr/share/nagios4/htdocs|/usr/lib/cgi-bin/nagios4|/etc/nagios4/stylesheets)>
    Options FollowSymLinks
    DirectoryIndex index.php index.html
    AllowOverride AuthConfig
    AuthDigestDomain "Nagios4"
    AuthDigestProvider file
    AuthUserFile	"{{ auth_file }}"
    AuthGroupFile	"/etc/group"
    AuthName	"{{ realm }}"
    AuthType	Digest
    Require	valid-user
</DirectoryMatch>

<Directory /usr/share/nagios4/htdocs>
    Options	+ExecCGI	
</Directory>

Nagios configuration file for RHEL systems;

cat roles/nagios-server/templates/nagios.conf.j2
<ScriptAlias /nagios/cgi-bin "/usr/lib64/nagios/cgi-bin/">

<Directory "/usr/lib64/nagios/cgi-bin/">
#  SSLRequireSSL
   Options ExecCGI
   AllowOverride None
   AuthName "Nagios Access"
   AuthType Basic
   AuthUserFile {{ auth_file }}
   Require valid-user
</Directory>

<Alias /nagios "/usr/share/nagios/html">

<Directory "/usr/share/nagios/html">
#  SSLRequireSSL
   Options None
   AllowOverride None
   AuthName "Nagios Access"
   AuthType Basic
   AuthUserFile {{ auth_file }}
   Require valid-user
</Directory>

Nagios Host and Service Definition templates:

cat roles/nagios-server/templates/template.cfg.j2
#################### HOSTS Templates ##########################
define host{
    name                           {{ host_template }}
    active_checks_enabled          1
    notifications_enabled          1
    event_handler_enabled          1
    flap_detection_enabled         1
    process_perf_data              1
    retain_status_information      1
    retain_nonstatus_information   1
    check_command                  check-host-alive
    check_interval                 5
    max_check_attempts             2
    notification_interval          60
    notification_period            24x7
    notification_options           d,u,r
    contact_groups                 {{ contact_group_name }}
    register                       0
}

######################## SERVICES TEMPLATES #################################

define service{
    name                           {{ svc_template }}
    active_checks_enabled          1
    passive_checks_enabled         1
    parallelize_check              1
    obsess_over_service            1
    check_freshness                0
    notifications_enabled          1
    event_handler_enabled          1
    flap_detection_enabled         1
    process_perf_data              1
    retain_status_information      1
    retain_nonstatus_information   1
    notification_interval          60
    is_volatile                    0
    check_period                   24x7
    check_interval                 5
    retry_interval                 1
    max_check_attempts             2
    notification_period            24x7
    notification_options           w,u,c,r
    contact_groups                 {{ contact_group_name }}
    register                       0
}

Variables for all systems, Debian and RHEL systems:

cat roles/nagios-server/vars/Debian.yaml

(We stored user credentials in plain text in the variables file, you can consider storing them in vault.)

nagios_users:
  - username: nagiosadmin
    password: "{{ ('nagiosadmin:' ~ realm ~ ':admin') | hash('md5') }}"
    role: admin
  - username: johndoe
    password: "{{ ('nagiosadmin:' ~ realm ~ ':johnd') | hash('md5') }}"
    role: admin
  - username: janedoe
    password: "{{ ('nagiosadmin:' ~ realm ~ ':janed') | hash('md5') }}"
    role: admin
  - username: nagiosmonitor
    password: "{{ ('nagiosmonitor:' ~ realm ~ ':nagmon') | hash('md5') }}"
    role: readonly
  - username: nagiosmonitor2
    password: "{{ ('nagiosmonitor2:' ~ realm ~ ':nagmon2') | hash('md5') }}"
    role: readonly
  - username: nagiosmonitor3
    password: "{{ ('nagiosmonitor3:' ~ realm ~ ':nagmon3') | hash('md5') }}"
    role: readonly
realm: Nagios4
auth_file: /etc/nagios4/htdigest.users
nagios_custom_configs_dir: /etc/nagios4/objects/kifarunix
nagios_parent_config_dir: /etc/nagios4
apache_parent_config_dir: /etc/apache2
apache_nagios_config: /etc/apache2/conf-available/nagios4-cgi.conf
nagios_cgi_config: /etc/nagios4/cgi.cfg
nagios_main_config: /etc/nagios4/nagios.cfg
nagios_plugins_dir: /usr/lib/nagios/plugins
apache_service: apache2
nagios_service: nagios4
nagios_bin: /usr/sbin/nagios4
apache_bin: /usr/sbin/apache2ctl

Main variables:

cat roles/nagios-server/vars/main.yaml
nagios_users:
  - username: nagiosadmin
    password: "{{ 'nagiosadmin:{{ realm }}:admin' | hash('md5') }}"
    role: admin
  - username: johndoe
    password: "{{ 'nagiosadmin:{{ realm }}:admin' | hash('md5') }}"
    role: admin
  - username: janedoe
    password: "{{ 'nagiosadmin:{{ realm }}:admin' | hash('md5') }}"
    role: admin
  - username: nagiosmonitor
    password: "{{ 'nagiosmonitor:{{ realm }}:monitor' | hash('md5') }}"
    role: readonly
  - username: nagiosmonitor2
    password: "{{ 'nagiosmonitor2:{{ realm }}:monitor2' | hash('md5') }}"
    role: readonly
  - username: nagiosmonitor3
    password: "{{ 'nagiosmonitor3:{{ realm }}:monitor3' | hash('md5') }}"
    role: readonly
contact_name: kifarunix-it-admins
contact_alias: "Kifarunix IT Admins"
email: "[email protected]"
contact_group_name: it-infra-admins
contact_group_alias: "Kifarunix IT Admins"
host_template: kifarunix-hosts
svc_template: kifarunix-services
general_group_name: "Kifarunix Nodes"
command_name: check_nrpe_agent

Variales for RHEL systems;

cat roles/nagios-server/vars/RedHat.yaml
nagios_users:
  - username: nagiosadmin
    password: admin
    role: admin
  - username: johndoe
    password: johnd
    role: admin
  - username: janedoe
    password: janed
    role: admin
  - username: nagiosmonitor
    password: nagmon
    role: readonly
  - username: nagiosmonitor2
    password: nagmon2
    role: readonly
  - username: nagiosmonitor3
    password: nagiosmon3
    role: readonly
auth_file: /etc/nagios/passwd
nagios_custom_configs_dir: /etc/nagios/objects/kifarunix
nagios_parent_config_dir: /etc/nagios
apache_parent_config_dir: /etc/httpd
apache_nagios_config: /etc/httpd/conf.d/nagios.conf
nagios_cgi_config: /etc/nagios/cgi.cfg
nagios_main_config: /etc/nagios/nagios.cfg
nagios_plugins_dir: /usr/lib64/nagios/plugins
apache_service: httpd
nagios_service: nagios
nagios_bin: /usr/sbin/nagios
apache_bin: /usr/sbin/httpd

Main Playbook for Deploying Nagios

The site.yaml file is typically the main playbook for deploying the entire Nagios monitoring stack. It includes references to the roles that need to be applied to the various hosts defined in the inventory file (nagios-inventory/hosts).

cat site.yaml
---
- name: Uninstall Nagios and NRPE Agents
  hosts: all
  gather_facts: True
  become: yes
  roles:
    - clean
  tags: clean

- name: Setup Nagios Server
  hosts: nagios-server
  gather_facts: True
  become: yes
  roles:
    - nagios-server

- name: Setup Nagios NRPE Agents
  hosts: nagios-nrpe-agents
  gather_facts: True
  become: yes
  roles:
    - nagios-nrpe-agents

All the roles will be executed in the order defined. A summary of execution flow is:

  • Cleanup: The first task runs on all hosts and removes Nagios and NRPE agents (if installed).
  • Nagios Server Setup: The second task configures the Nagios server on the designated host(s).
  • NRPE Agent Setup: The third task configures the NRPE agents on the designated host(s).

Note that you can also set tags against each role to make it easy to control what roles to execute.

For example, let’s set same tag for installation and setup of Nagios and NRPE agents;

---
- name: Uninstall Nagios and NRPE Agents
  hosts: all
  gather_facts: True
  become: yes
  roles:
    - clean
  tags: clean

- name: Setup Nagios Server
  hosts: nagios-server
  gather_facts: True
  become: yes
  roles:
    - nagios-server
  tags: nagios-setup

- name: Setup Nagios NRPE Agents
  hosts: nagios-nrpe-agents
  gather_facts: True
  become: yes
  roles:
    - nagios-nrpe-agents
  tags: nagios-setup

You can then call specific role execution using tags (–tags <tag-name>)

Perform Nagios Monitoring Stack Deployment via Ansible Dry Run

Performing a dry run allows you to see what changes would be made to your infrastructure without actually applying those changes. This is particularly useful for validating and testing your playbook before making real modifications.

Thus, navigate to your working directory and execute the playbook run!

ansible-playbook -i nagios-inventory/hosts site.yaml --check

Sample output;

[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

PLAY [Uninstall Nagios and NRPE Agents] ***************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [192.168.122.152]
ok: [192.168.122.11]
ok: [192.168.122.110]
ok: [192.168.122.79]
ok: [192.168.122.127]
ok: [192.168.122.174]

TASK [clean : include_vars] ***************************************************************************************************************************************************************************************
ok: [192.168.122.127] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.127] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)
ok: [192.168.122.11] => (item=../../nagios-server/vars/RedHat.yaml)
ok: [192.168.122.11] => (item=../../nagios-nrpe-agents/vars/RedHat.yaml)
ok: [192.168.122.152] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.152] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)
ok: [192.168.122.110] => (item=../../nagios-server/vars/RedHat.yaml)
ok: [192.168.122.110] => (item=../../nagios-nrpe-agents/vars/RedHat.yaml)
ok: [192.168.122.79] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.79] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)
ok: [192.168.122.174] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.174] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)

TASK [clean : Uninstall Nagios in Debian systems] *****************************************************************************************************************************************************************
skipping: [192.168.122.11]
skipping: [192.168.122.110]
ok: [192.168.122.152]
ok: [192.168.122.174]
ok: [192.168.122.127]
ok: [192.168.122.79]

TASK [clean : Uninstall Nagios in RHEL systems] *******************************************************************************************************************************************************************
skipping: [192.168.122.127]
skipping: [192.168.122.152]
skipping: [192.168.122.79]
skipping: [192.168.122.174]
ok: [192.168.122.11]
ok: [192.168.122.110]

TASK [clean : Remove Nagios configs dir if it has custom configs] *************************************************************************************************************************************************
ok: [192.168.122.152] => (item=/etc/nagios4)
ok: [192.168.122.127] => (item=/etc/nagios4)
ok: [192.168.122.79] => (item=/etc/nagios4)
ok: [192.168.122.11] => (item=/etc/nagios)
ok: [192.168.122.110] => (item=/etc/nagios)
ok: [192.168.122.152] => (item=/etc/apache2)
ok: [192.168.122.127] => (item=/etc/apache2)
ok: [192.168.122.79] => (item=/etc/apache2)
ok: [192.168.122.11] => (item=/etc/httpd)
ok: [192.168.122.174] => (item=/etc/nagios4)
ok: [192.168.122.110] => (item=/etc/httpd)
ok: [192.168.122.174] => (item=/etc/apache2)

TASK [clean : Un-Install NRPE on Debian systems] ******************************************************************************************************************************************************************
skipping: [192.168.122.11]
skipping: [192.168.122.110]
ok: [192.168.122.152]
ok: [192.168.122.127]
ok: [192.168.122.174]
ok: [192.168.122.79]

TASK [clean : Install NRPE on RedHat systems] *********************************************************************************************************************************************************************
skipping: [192.168.122.127]
skipping: [192.168.122.152]
skipping: [192.168.122.79]
skipping: [192.168.122.174]
ok: [192.168.122.11]
ok: [192.168.122.110]

TASK [clean : Remove NRPE configs dir if it has custom configs] ***************************************************************************************************************************************************
ok: [192.168.122.152]
ok: [192.168.122.127]
ok: [192.168.122.11]
ok: [192.168.122.79]
ok: [192.168.122.110]
ok: [192.168.122.174]

PLAY [Setup Nagios Server] ****************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [192.168.122.11]
ok: [192.168.122.127]

TASK [nagios-server : include_vars] *******************************************************************************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Install Nagios4 and Monitoring Plugins on Debian-based systems] *****************************************************************************************************************************
skipping: [192.168.122.11]
changed: [192.168.122.127]

TASK [nagios-server : Install Nagios4 and Monitoring Plugins on RHEL-based systems] *******************************************************************************************************************************
skipping: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Apache-Nagios Config for Debian] ************************************************************************************************************************************************************
skipping: [192.168.122.11]
changed: [192.168.122.127]

TASK [nagios-server : Apache-Nagios Config for Redhat] ************************************************************************************************************************************************************
skipping: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Enable Apache rewrite, cgi, auth_digest, authz_groupfile modules] ***************************************************************************************************************************
skipping: [192.168.122.11] => (item={'module': 'rewrite', 'state': 'present'}) 
skipping: [192.168.122.11] => (item={'module': 'cgi', 'state': 'present'}) 
skipping: [192.168.122.11] => (item={'module': 'auth_digest', 'state': 'present'}) 
skipping: [192.168.122.11] => (item={'module': 'authz_groupfile', 'state': 'present'}) 
skipping: [192.168.122.11]
failed: [192.168.122.127] (item={'module': 'rewrite', 'state': 'present'}) => {"ansible_loop_var": "item", "changed": false, "item": {"module": "rewrite", "state": "present"}, "msg": "Neither of apache2ctl nor apachectl found. At least one apache control binary is necessary."}
failed: [192.168.122.127] (item={'module': 'cgi', 'state': 'present'}) => {"ansible_loop_var": "item", "changed": false, "item": {"module": "cgi", "state": "present"}, "msg": "Neither of apache2ctl nor apachectl found. At least one apache control binary is necessary."}
failed: [192.168.122.127] (item={'module': 'auth_digest', 'state': 'present'}) => {"ansible_loop_var": "item", "changed": false, "item": {"module": "auth_digest", "state": "present"}, "msg": "Neither of apache2ctl nor apachectl found. At least one apache control binary is necessary."}
failed: [192.168.122.127] (item={'module': 'authz_groupfile', 'state': 'present'}) => {"ansible_loop_var": "item", "changed": false, "item": {"module": "authz_groupfile", "state": "present"}, "msg": "Neither of apache2ctl nor apachectl found. At least one apache control binary is necessary."}

TASK [nagios-server : Add users to auth file on Debian] ***********************************************************************************************************************************************************
skipping: [192.168.122.11]

TASK [nagios-server : Ensure the htpasswd file exists] ************************************************************************************************************************************************************
changed: [192.168.122.11]

TASK [nagios-server : Add users to auth file on RHEL] *************************************************************************************************************************************************************
skipping: [192.168.122.11] => (item={'username': 'nagiosadmin', 'password': 'admin', 'role': 'admin'}) 
skipping: [192.168.122.11] => (item={'username': 'johndoe', 'password': 'johnd', 'role': 'admin'}) 
skipping: [192.168.122.11] => (item={'username': 'janedoe', 'password': 'janed', 'role': 'admin'}) 
skipping: [192.168.122.11] => (item={'username': 'nagiosmonitor', 'password': 'nagmon', 'role': 'readonly'}) 
skipping: [192.168.122.11] => (item={'username': 'nagiosmonitor2', 'password': 'nagmon2', 'role': 'readonly'}) 
skipping: [192.168.122.11] => (item={'username': 'nagiosmonitor3', 'password': 'nagiosmon3', 'role': 'readonly'}) 
skipping: [192.168.122.11]

TASK [nagios-server : Enable authentication] **********************************************************************************************************************************************************************
fatal: [192.168.122.11]: FAILED! => {"changed": false, "msg": "Destination /etc/nagios/cgi.cfg does not exist !", "rc": 257}

PLAY RECAP ********************************************************************************************************************************************************************************************************
192.168.122.11             : ok=11   changed=3    unreachable=0    failed=1    skipped=7    rescued=0    ignored=0   
192.168.122.110            : ok=6    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
192.168.122.127            : ok=10   changed=2    unreachable=0    failed=1    skipped=4    rescued=0    ignored=0   
192.168.122.152            : ok=6    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
192.168.122.174            : ok=6    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0   
192.168.122.79             : ok=6    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

To check specific roles;

ansible-playbook -i nagios-inventory/hosts site.yaml --check --tags nagios-setup

Or

ansible-playbook -i nagios-inventory/hosts site.yaml --check --tags clean

Deploy Nagios Monitoring Stack with Ansible

Once you are confident with your playbook, execute it to install and setup Nagios monitoring.

ansible-playbook -i nagios-inventory/hosts site.yaml

Sample output;

[WARNING]: Invalid characters were found in group names but not replaced, use -vvvv to see details

PLAY [Uninstall Nagios and NRPE Agents] ***************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [192.168.122.152]
ok: [192.168.122.11]
ok: [192.168.122.110]
ok: [192.168.122.127]
ok: [192.168.122.79]
ok: [192.168.122.174]

TASK [clean : include_vars] ***************************************************************************************************************************************************************************************
ok: [192.168.122.127] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.127] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)
ok: [192.168.122.11] => (item=../../nagios-server/vars/RedHat.yaml)
ok: [192.168.122.11] => (item=../../nagios-nrpe-agents/vars/RedHat.yaml)
ok: [192.168.122.152] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.152] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)
ok: [192.168.122.110] => (item=../../nagios-server/vars/RedHat.yaml)
ok: [192.168.122.110] => (item=../../nagios-nrpe-agents/vars/RedHat.yaml)
ok: [192.168.122.79] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.79] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)
ok: [192.168.122.174] => (item=../../nagios-server/vars/Debian.yaml)
ok: [192.168.122.174] => (item=../../nagios-nrpe-agents/vars/Debian.yaml)

TASK [clean : Uninstall Nagios in Debian systems] *****************************************************************************************************************************************************************
skipping: [192.168.122.11]
skipping: [192.168.122.110]
ok: [192.168.122.152]
ok: [192.168.122.79]
ok: [192.168.122.174]
changed: [192.168.122.127]

TASK [clean : Uninstall Nagios in RHEL systems] *******************************************************************************************************************************************************************
skipping: [192.168.122.127]
skipping: [192.168.122.152]
skipping: [192.168.122.79]
skipping: [192.168.122.174]
ok: [192.168.122.110]
changed: [192.168.122.11]

TASK [clean : Remove Nagios configs dir if it has custom configs] *************************************************************************************************************************************************
ok: [192.168.122.152] => (item=/etc/nagios4)
changed: [192.168.122.127] => (item=/etc/nagios4)
ok: [192.168.122.79] => (item=/etc/nagios4)
changed: [192.168.122.11] => (item=/etc/nagios)
ok: [192.168.122.110] => (item=/etc/nagios)
ok: [192.168.122.152] => (item=/etc/apache2)
ok: [192.168.122.79] => (item=/etc/apache2)
ok: [192.168.122.127] => (item=/etc/apache2)
changed: [192.168.122.11] => (item=/etc/httpd)
ok: [192.168.122.174] => (item=/etc/nagios4)
ok: [192.168.122.110] => (item=/etc/httpd)
ok: [192.168.122.174] => (item=/etc/apache2)

TASK [clean : Un-Install NRPE on Debian systems] ******************************************************************************************************************************************************************
skipping: [192.168.122.11]
skipping: [192.168.122.110]
ok: [192.168.122.152]
ok: [192.168.122.127]
ok: [192.168.122.79]
ok: [192.168.122.174]

TASK [clean : Install NRPE on RedHat systems] *********************************************************************************************************************************************************************
skipping: [192.168.122.127]
skipping: [192.168.122.152]
skipping: [192.168.122.79]
skipping: [192.168.122.174]
ok: [192.168.122.11]
ok: [192.168.122.110]

TASK [clean : Remove NRPE configs dir if it has custom configs] ***************************************************************************************************************************************************
ok: [192.168.122.152]
ok: [192.168.122.127]
ok: [192.168.122.79]
ok: [192.168.122.11]
ok: [192.168.122.110]
ok: [192.168.122.174]

PLAY [Setup Nagios Server] ****************************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [192.168.122.11]
ok: [192.168.122.127]

TASK [nagios-server : include_vars] *******************************************************************************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Install Nagios4 and Monitoring Plugins on Debian-based systems] *****************************************************************************************************************************
skipping: [192.168.122.11]
changed: [192.168.122.127]

TASK [nagios-server : Install Nagios4 and Monitoring Plugins on RHEL-based systems] *******************************************************************************************************************************
skipping: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Apache-Nagios Config for Debian] ************************************************************************************************************************************************************
skipping: [192.168.122.11]
changed: [192.168.122.127]

TASK [nagios-server : Apache-Nagios Config for Redhat] ************************************************************************************************************************************************************
skipping: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Enable Apache rewrite, cgi, auth_digest, authz_groupfile modules] ***************************************************************************************************************************
skipping: [192.168.122.11] => (item={'module': 'rewrite', 'state': 'present'}) 
skipping: [192.168.122.11] => (item={'module': 'cgi', 'state': 'present'}) 
skipping: [192.168.122.11] => (item={'module': 'auth_digest', 'state': 'present'}) 
skipping: [192.168.122.11] => (item={'module': 'authz_groupfile', 'state': 'present'}) 
skipping: [192.168.122.11]
changed: [192.168.122.127] => (item={'module': 'rewrite', 'state': 'present'})
changed: [192.168.122.127] => (item={'module': 'cgi', 'state': 'present'})
ok: [192.168.122.127] => (item={'module': 'auth_digest', 'state': 'present'})
ok: [192.168.122.127] => (item={'module': 'authz_groupfile', 'state': 'present'})

TASK [nagios-server : Add users to auth file on Debian] ***********************************************************************************************************************************************************
skipping: [192.168.122.11]
changed: [192.168.122.127]

TASK [nagios-server : Ensure the htpasswd file exists] ************************************************************************************************************************************************************
skipping: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Add users to auth file on RHEL] *************************************************************************************************************************************************************
skipping: [192.168.122.127] => (item={'username': 'nagiosadmin', 'password': 'b5d217c46a89ca8c0a06b066d943803f', 'role': 'admin'}) 
skipping: [192.168.122.127] => (item={'username': 'johndoe', 'password': '84aba8686ef432b184a3ec93bba26f06', 'role': 'admin'}) 
skipping: [192.168.122.127] => (item={'username': 'janedoe', 'password': 'a54b71bd00b8fdb000ab426ae23a8df5', 'role': 'admin'}) 
skipping: [192.168.122.127] => (item={'username': 'nagiosmonitor', 'password': '36c59f656f0bd66e8b715d9424beec72', 'role': 'readonly'}) 
skipping: [192.168.122.127] => (item={'username': 'nagiosmonitor2', 'password': 'deb28e03cf25cb30837df2f85f339389', 'role': 'readonly'}) 
skipping: [192.168.122.127] => (item={'username': 'nagiosmonitor3', 'password': 'f659dbf8c797620ef669ce11a42c4835', 'role': 'readonly'}) 
skipping: [192.168.122.127]
changed: [192.168.122.11] => (item={'username': 'nagiosadmin', 'password': 'admin', 'role': 'admin'})
changed: [192.168.122.11] => (item={'username': 'johndoe', 'password': 'johnd', 'role': 'admin'})
changed: [192.168.122.11] => (item={'username': 'janedoe', 'password': 'janed', 'role': 'admin'})
changed: [192.168.122.11] => (item={'username': 'nagiosmonitor', 'password': 'nagmon', 'role': 'readonly'})
changed: [192.168.122.11] => (item={'username': 'nagiosmonitor2', 'password': 'nagmon2', 'role': 'readonly'})
changed: [192.168.122.11] => (item={'username': 'nagiosmonitor3', 'password': 'nagiosmon3', 'role': 'readonly'})

TASK [nagios-server : Enable authentication] **********************************************************************************************************************************************************************
changed: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Get list of Nagios admin users] *************************************************************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Check if the admin user_list is already in the Nagios config file] **************************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Check if the readonly user list is already in the Nagios config file] ***********************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Define admins users] ************************************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Define read-only users] *********************************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Set Results Display Limit to 0] *************************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Create Nagios custom configs directory] *****************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Add Nagios Custom Configurations Directory] *************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Ensure the Nagios custom configs directory exists] ******************************************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Install Check commands configuration] *******************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Install Nagios Contacts configuration] ******************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Install Nagios Hosts and Services Definition Template] **************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Define Nagios Hosts and Host Groups] ********************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Create Service Definition] ******************************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : Check Nagios Syntax] ************************************************************************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Show some info if Nagios syntax check fail] *************************************************************************************************************************************************
skipping: [192.168.122.127]
skipping: [192.168.122.11]

TASK [nagios-server : Check Apache Syntax] ************************************************************************************************************************************************************************
ok: [192.168.122.127]
ok: [192.168.122.11]

TASK [nagios-server : Show some info if Apache syntax check fail] *************************************************************************************************************************************************
skipping: [192.168.122.127]
skipping: [192.168.122.11]

TASK [nagios-server : (Re)start Nagios] ***************************************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

TASK [nagios-server : (Re)start Apache] ***************************************************************************************************************************************************************************
changed: [192.168.122.127]
changed: [192.168.122.11]

PLAY [Setup Nagios NRPE Agents] ***********************************************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************************************************************
ok: [192.168.122.152]
ok: [192.168.122.110]
ok: [192.168.122.79]
ok: [192.168.122.174]

TASK [nagios-nrpe-agents : include_vars] **************************************************************************************************************************************************************************
ok: [192.168.122.152]
ok: [192.168.122.110]
ok: [192.168.122.79]
ok: [192.168.122.174]

TASK [nagios-nrpe-agents : Install NRPE and Nagios plugins on Debian/Ubuntu] **************************************************************************************************************************************
skipping: [192.168.122.110]
changed: [192.168.122.152]
changed: [192.168.122.79]
changed: [192.168.122.174]

TASK [nagios-nrpe-agents : Install NRPE and Nagios plugins on CentOS/RedHat/Rocky] ********************************************************************************************************************************
skipping: [192.168.122.152]
skipping: [192.168.122.79]
skipping: [192.168.122.174]
changed: [192.168.122.110]

TASK [nagios-nrpe-agents : Configure NRPE Agent using template] ***************************************************************************************************************************************************
changed: [192.168.122.152]
changed: [192.168.122.174]
changed: [192.168.122.79]
changed: [192.168.122.110]

TASK [nagios-nrpe-agents : Copy check_memory script] **************************************************************************************************************************************************************
ok: [192.168.122.152]
ok: [192.168.122.174]
ok: [192.168.122.79]
ok: [192.168.122.110]

TASK [nagios-nrpe-agents : Disble NRPE SSL Support on Debian] *****************************************************************************************************************************************************
skipping: [192.168.122.110]
ok: [192.168.122.152]
ok: [192.168.122.174]
ok: [192.168.122.79]

TASK [nagios-nrpe-agents : Disble NRPE SSL Support on RHEL] *******************************************************************************************************************************************************
skipping: [192.168.122.152]
skipping: [192.168.122.79]
skipping: [192.168.122.174]
changed: [192.168.122.110]

TASK [nagios-nrpe-agents : Restart NRPE service] ******************************************************************************************************************************************************************
changed: [192.168.122.152]
changed: [192.168.122.174]
changed: [192.168.122.79]
changed: [192.168.122.110]

PLAY RECAP ********************************************************************************************************************************************************************************************************
192.168.122.11             : ok=31   changed=18   unreachable=0    failed=0    skipped=8    rescued=0    ignored=0   
192.168.122.110            : ok=13   changed=4    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0   
192.168.122.127            : ok=31   changed=19   unreachable=0    failed=0    skipped=8    rescued=0    ignored=0   
192.168.122.152            : ok=13   changed=3    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0   
192.168.122.174            : ok=13   changed=3    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0   
192.168.122.79             : ok=13   changed=3    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0

You can skip the clean part!

ansible-playbook -i nagios-inventory/hosts site.yaml --tags nagios-setup

Verify Nagios Setup

Remember, our two Nagios servers are:

  • 192.168.122.11 (CentOS 9 Stream): http://192.168.122.11/nagios
  • 192.168.122.127 (Debian 12): http://192.168.122.127/nagios4

Login page, Debian;

nagios deployment via ansible login page on Debian

Login page on RHEL;

nagios deployment via ansible login page on RHEL

Hosts Status;

Full Automation of Nagios Monitoring Setup with Ansible

Sample NRPE Agent configuration on the monitored hosts;

cat /etc/nagios/nrpe.cfg
log_facility=daemon
server_port=5666
nrpe_user=nagios
nrpe_group=nagios
allowed_hosts=127.0.0.1,192.168.122.127,192.168.122.11
dont_blame_nrpe=1
debug=0
command_timeout=60
connection_timeout=300
command[check_disk]=/usr/lib/nagios/plugins/check_disk -w 20% -c 10% -p /
command[check_users]=/usr/lib/nagios/plugins/check_users -w 5 -c 10
command[check_load]=/usr/lib/nagios/plugins/check_load -w 2.8,2.8,2.8 -c 3.2,3.2,3.2
command[check_procs]=/usr/lib/nagios/plugins/check_procs -w 1000 -c 1500
command[check_memory]=/usr/lib/nagios/plugins/check_memory -w 80 -c 90
command[check_swap]=/usr/lib/nagios/plugins/check_swap -w 20% -c 10%
command[check_zombie_procs]=/usr/lib/nagios/plugins/check_procs -w 5 -c 10 -s Z

And that confirms that the full automation of Nagios monitoring setup has been successful.

Clean Nagios Setup via Ansible

As you can see, we have also included a role to uninstall and clean all Nagios related packages on the systems.

You can just run this command to clean both Nagios server and NRPE agents installation/setup.

ansible-playbook -i nagios-inventory/hosts site.yaml --tags clean

Otherwise, to remove NRPE agents only;

ansible-playbook -i nagios-inventory/hosts site.yaml --tags clean --limit nagios-nrpe-agents

To remove Nagios server;

ansible-playbook -i nagios-inventory/hosts site.yaml --tags clean --limit nagios-server

That marks the end of our guide on full automation of Nagios monitoring setup with Ansible. Feel free to test this out and give feedback!

Deploy ELK Stack 8 Cluster on Docker using Ansible

Deploy Nagios NRPE Agents using Ansible

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
Kifarunix
Linux Certified Engineer, with a passion for open-source technology and a strong understanding of Linux systems. With experience in system administration, troubleshooting, and automation, I am skilled in maintaining and optimizing Linux infrastructure.

Leave a Comment