This guide provides a complete Ansible playbook to install Icinga 2 with Icinga Web 2, database backend, and monitoring capabilities.
Current Icinga 2 version: 2.15.2
Create a file named icinga2.yml:
---
- name: Install and Configure Icinga 2
hosts: icinga
become: true
vars:
icinga2_version: "2.15"
icinga_web_version: "2.12"
icinga_port: 5665
icinga_agent_port: 5666
web_port: 80
db_type: "mysql" # or postgresql
db_name: "icinga"
db_user: "icinga"
db_password: "icinga_secure_password_123"
icingaweb_db_name: "icingaweb2"
icingaweb_db_user: "icingaweb"
icingaweb_db_password: "icingaweb_secure_456"
icinga_admin_password: "icinga_admin_789" # Change this!
tasks:
- name: Install prerequisites (Debian/Ubuntu)
apt:
name:
- apt-transport-https
- software-properties-common
- wget
- gnupg2
- lsb-release
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Add Icinga APT key (Debian/Ubuntu)
apt_key:
url: "https://packages.icinga.com/icinga.key"
state: present
when: ansible_os_family == "Debian"
- name: Add Icinga APT repository (Debian/Ubuntu)
apt_repository:
repo: "deb https://packages.icinga.com/debian icinga-{{ ansible_distribution_release }} main"
state: present
filename: icinga
when: ansible_os_family == "Debian"
- name: Install Icinga 2 repository (RHEL/CentOS)
yum:
name: "https://packages.icinga.com/epel/icinga-rpm-release-{{ ansible_distribution_major_version }}-latest.noarch.rpm"
state: present
when: ansible_os_family == "RedHat"
- name: Install MySQL server
package:
name:
- mysql-server
- mysql-client
state: present
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Install MariaDB server (RHEL)
yum:
name:
- mariadb-server
- mariadb
state: present
when: ansible_os_family == "RedHat" and db_type == 'mysql'
- name: Start and enable MySQL
systemd:
name: "{{ 'mysql' if ansible_os_family == 'Debian' else 'mariadb' }}"
enabled: true
state: started
- name: Install Icinga 2 and components
package:
name:
- icinga2
- icinga2-bin
- icinga-common
- monitoring-plugins-basic
- monitoring-plugins-standard
state: present
when: ansible_os_family == "RedHat"
- name: Install Icinga 2 (Debian/Ubuntu)
apt:
name:
- icinga2
- icinga2-bin
- icinga-common
- monitoring-plugins-basic
- monitoring-plugins-standard
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install Icinga 2 IDO MySQL
package:
name: icinga2-ido-mysql
state: present
when: ansible_os_family == "RedHat" and db_type == 'mysql'
- name: Install Icinga 2 IDO MySQL (Debian/Ubuntu)
apt:
name: icinga2-ido-mysql
state: present
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Install Icinga Web 2 and dependencies
package:
name:
- icingaweb2
- icingacli
- php
- php-mysql
- php-gd
- php-ldap
- php-intl
- php-imagick
- php-curl
state: present
when: ansible_os_family == "RedHat"
- name: Install Icinga Web 2 (Debian/Ubuntu)
apt:
name:
- icingaweb2
- icingacli
- php
- php-mysql
- php-gd
- php-ldap
- php-intl
- php-imagick
- php-curl
state: present
when: ansible_os_family == "Debian"
- name: Create Icinga database
mysql_db:
name: "{{ db_name }}"
encoding: utf8
login_unix_socket: /var/run/mysqld/mysqld.sock
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Create Icinga database user
mysql_user:
name: "{{ db_user }}"
password: "{{ db_password }}"
priv: "{{ db_name }}.*:ALL"
host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Import Icinga 2 schema
mysql:
login_unix_socket: /var/run/mysqld/mysqld.sock
target:
- /usr/share/icinga2-ido-mysql/schema/mysql.sql
name: "{{ db_name }}"
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Configure Icinga 2 IDO MySQL
template:
src: ido-mysql.conf.j2
dest: /etc/icinga2/features-available/ido-mysql.conf
owner: root
group: icinga2
mode: '0640'
vars:
ido_db_host: "localhost"
ido_db_name: "{{ db_name }}"
ido_db_user: "{{ db_user }}"
ido_db_password: "{{ db_password }}"
- name: Enable IDO MySQL feature
command: icinga2 feature enable ido-mysql
args:
creates: /etc/icinga2/features-enabled/ido-mysql.conf
- name: Enable mainlog feature
command: icinga2 feature enable mainlog
args:
creates: /etc/icinga2/features-enabled/mainlog.conf
- name: Enable checker feature
command: icinga2 feature enable checker
args:
creates: /etc/icinga2/features-enabled/checker.conf
- name: Enable api feature
command: icinga2 feature enable api
args:
creates: /etc/icinga2/features-enabled/api.conf
- name: Configure Icinga 2 API
lineinfile:
path: /etc/icinga2/features-available/api.conf
regexp: "^#?\s*{{ item.key }} ="
line: "{{ item.key }} = {{ item.value }}"
loop:
- { key: 'bind_host', value: '0.0.0.0' }
- { key: 'bind_port', value: '{{ icinga_port }}' }
- name: Create Icinga Web 2 database
mysql_db:
name: "{{ icingaweb_db_name }}"
encoding: utf8
login_unix_socket: /var/run/mysqld/mysqld.sock
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Create Icinga Web 2 database user
mysql_user:
name: "{{ icingaweb_db_user }}"
password: "{{ icingaweb_db_password }}"
priv: "{{ icingaweb_db_name }}.*:ALL"
host: localhost
login_unix_socket: /var/run/mysqld/mysqld.sock
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Import Icinga Web 2 schema
mysql:
login_unix_socket: /var/run/mysqld/mysqld.sock
target:
- /usr/share/doc/icingaweb2/schema/mysql.schema.sql
name: "{{ icingaweb_db_name }}"
when: ansible_os_family == "Debian" and db_type == 'mysql'
- name: Configure Icinga Web 2 database
copy:
dest: /etc/icingaweb2/resources.ini
owner: www-data
group: www-data
mode: '0640'
content: |
[icingaweb2]
type = "db"
db = "mysql"
host = "localhost"
port = "3306"
dbname = "{{ icingaweb_db_name }}"
username = "{{ icingaweb_db_user }}"
password = "{{ icingaweb_db_password }}"
when: ansible_os_family == "Debian"
- name: Create Icinga Web 2 authentication
copy:
dest: /etc/icingaweb2/authentication.ini
owner: www-data
group: www-data
mode: '0640'
content: |
[icingaweb2]
backend = "db"
resource = "icingaweb2"
user_class = "user"
user_filter = "active = 1"
group_class = "group"
group_filter = "active = 1"
when: ansible_os_family == "Debian"
- name: Create Icinga Web 2 admin user
command: >
icingacli user create admin
--password={{ icinga_admin_password }}
--email=admin@example.com
args:
creates: /tmp/icinga_admin_created
when: ansible_os_family == "Debian"
- name: Create admin created marker
file:
path: /tmp/icinga_admin_created
state: touch
when: ansible_os_family == "Debian"
- name: Assign admin to administrators group
command: icingacli user group set admin administrators
args:
creates: /tmp/icinga_admin_group_set
when: ansible_os_family == "Debian"
- name: Create admin group marker
file:
path: /tmp/icinga_admin_group_set
state: touch
when: ansible_os_family == "Debian"
- name: Enable and start Icinga 2
systemd:
name: icinga2
enabled: true
state: started
- name: Restart Apache web server
systemd:
name: apache2
enabled: true
state: restarted
when: ansible_os_family == "Debian"
- name: Restart httpd (RHEL)
systemd:
name: httpd
enabled: true
state: restarted
when: ansible_os_family == "RedHat"
- name: Configure firewall (UFW)
ufw:
rule: allow
port: "{{ item }}"
proto: tcp
comment: "Icinga 2"
loop:
- "{{ icinga_port }}"
- "{{ icinga_agent_port }}"
- "{{ web_port }}"
when: ansible_os_family == "Debian"
failed_when: false
- name: Configure firewall (firewalld)
firewalld:
port: "{{ item }}/tcp"
permanent: true
immediate: true
state: enabled
loop:
- "{{ icinga_port }}"
- "{{ icinga_agent_port }}"
- "80"
- "443"
when: ansible_os_family == "RedHat"
failed_when: false
- name: Verify Icinga 2 configuration
command: icinga2 daemon -C
register: icinga_verify
changed_when: false
failed_when: icinga_verify.rc != 0
- name: Wait for Icinga Web 2
wait_for:
port: "{{ web_port }}"
delay: 5
timeout: 60
- name: Display Icinga status
debug:
msg: |
Icinga 2 {{ icinga2_version }} installed successfully!
Web Interface: http://{{ ansible_default_ipv4.address | default(ansible_host) }}/icingaweb2
Username: admin
Password: {{ icinga_admin_password }}
API Port: {{ icinga_port }}
Agent Port: {{ icinga_agent_port }}
IMPORTANT: Change the default password after first login!
---
icinga:
hosts:
icinga-server:
ansible_host: 192.168.1.105
ansible_user: ansible
ansible_become: true
# Test connectivity
ansible all -i inventory.yml -m ping
# Run the Icinga 2 playbook
ansible-playbook -i inventory.yml icinga2.yml
# Run with custom passwords
ansible-playbook -i inventory.yml icinga2.yml \
-e "db_password=MySecureDBPass123" \
-e "icingaweb_db_password=WebSecurePass456" \
-e "icinga_admin_password=AdminSecurePass789"
# Check Icinga 2 service status
ssh icinga-server "sudo systemctl status icinga2"
# Verify configuration
ssh icinga-server "sudo icinga2 daemon -C"
# Test web interface
curl -I http://icinga-server/icingaweb2
# Access web UI
# http://icinga-server/icingaweb2
- name: Add hosts to Icinga 2
hosts: icinga
become: true
vars:
icinga_conf_dir: "/etc/icinga2/conf.d"
tasks:
- name: Create hosts configuration directory
file:
path: "{{ icinga_conf_dir }}/hosts"
state: directory
owner: icinga2
group: icinga2
mode: '0755'
- name: Add host configuration
copy:
dest: "{{ icinga_conf_dir }}/hosts/{{ item.name }}.conf"
owner: icinga2
group: icinga2
mode: '0644'
content: |
object Host "{{ item.name }}" {
import "generic-host"
address = "{{ item.address }}"
vars.os = "linux"
}
apply Service "ping4" {
import "generic-service"
check_command = "ping4"
assign where host.name == "{{ item.name }}"
}
apply Service "ssh" {
import "generic-service"
check_command = "ssh"
assign where host.name == "{{ item.name }}" && host.vars.os == "linux"
}
apply Service "disk" {
import "generic-service"
check_command = "disk"
vars.disk = "/"
assign where host.name == "{{ item.name }}"
}
apply Service "load" {
import "generic-service"
check_command = "load"
assign where host.name == "{{ item.name }}"
}
apply Service "procs" {
import "generic-service"
check_command = "procs"
assign where host.name == "{{ item.name }}"
}
apply Service "users" {
import "generic-service"
check_command = "users"
assign where host.name == "{{ item.name }}"
}
loop: "{{ hosts_to_monitor }}"
- name: Validate Icinga 2 configuration
command: icinga2 daemon -C
register: icinga_verify
changed_when: false
- name: Restart Icinga 2
systemd:
name: icinga2
state: restarted
when: icinga_verify.rc == 0
- name: Install Icinga 2 Agent on monitored hosts
hosts: monitored_hosts
become: true
vars:
icinga_server_ip: "192.168.1.105"
icinga_agent_port: 5666
tasks:
- name: Add Icinga repository (Debian/Ubuntu)
apt_key:
url: "https://packages.icinga.com/icinga.key"
state: present
when: ansible_os_family == "Debian"
- name: Add Icinga APT repository
apt_repository:
repo: "deb https://packages.icinga.com/debian icinga-{{ ansible_distribution_release }} main"
state: present
when: ansible_os_family == "Debian"
- name: Install Icinga 2 Agent
apt:
name: icinga2
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Enable agent feature
command: icinga2 feature enable command
args:
creates: /etc/icinga2/features-enabled/command.conf
- name: Configure Icinga 2 agent
lineinfile:
path: /etc/icinga2/constants.conf
regexp: "^#?NodeName"
line: 'const NodeName = "{{ ansible_fqdn | default(ansible_hostname) }}"'
- name: Create agent endpoint configuration
copy:
dest: /etc/icinga2/zones.d/master/endpoints.conf
owner: icinga2
group: icinga2
mode: '0644'
content: |
object Endpoint "{{ ansible_fqdn | default(ansible_hostname) }}" {
host = "{{ ansible_default_ipv4.address | default(ansible_host) }}"
port = "{{ icinga_agent_port }}"
}
object Endpoint "{{ icinga_server_ip }}" {
host = "{{ icinga_server_ip }}"
}
object Zone "master" {
endpoints = [ "{{ ansible_fqdn | default(ansible_hostname) }}", "{{ icinga_server_ip }}" ]
}
object Zone "global-templates" {
global = true
}
object Zone "director-global" {
global = true
}
- name: Enable and start Icinga 2 agent
systemd:
name: icinga2
enabled: true
state: started
- name: Configure firewall for agent
ufw:
rule: allow
port: "{{ icinga_agent_port }}"
proto: tcp
when: ansible_os_family == "Debian"
failed_when: false
# Check logs
sudo journalctl -u icinga2 -f
# Verify configuration
sudo icinga2 daemon -C
# Check IDO connection
sudo mysql -u icinga -p -e "SELECT * FROM icinga_programs;"
# Check Apache logs
sudo tail -f /var/log/apache2/error.log
# Verify PHP configuration
php -i | grep -i date.timezone
# Check Icinga Web 2 logs
sudo tail -f /var/log/icingaweb2/icingaweb2.log
# Test agent connectivity
sudo icinga2 daemon -C
# Check agent logs
sudo tail -f /var/log/icinga2/debug.log
# Verify firewall rules
sudo ufw status
Beyond this playbook, we offer:
Contact our automation team: office@linux-server-admin.com