--- # Builds the Icinga2 master + Icinga Web 2 stack on Ubuntu (matches the # live install on monitor.vntx.net). Idempotent; safe to re-run. - name: Assert required vault values ansible.builtin.assert: that: - icinga2_ido_db_password is defined and icinga2_ido_db_password | length > 0 - icingaweb2_db_password is defined and icingaweb2_db_password | length > 0 - icingaweb2_ido_db_password is defined and icingaweb2_ido_db_password | length > 0 - icinga2_api_user_root_password is defined and icinga2_api_user_root_password | length > 0 - icinga2_api_user_icingaweb2_password is defined and icinga2_api_user_icingaweb2_password | length > 0 - icinga2_iftraffic_snmp_community is defined and icinga2_iftraffic_snmp_community | length > 0 fail_msg: >- Missing one or more required vault variables for the monitor role. See roles/monitor/README.md for the full list. # ----------- Repo + packages ----------- - name: Ensure /etc/apt/keyrings exists ansible.builtin.file: path: /etc/apt/keyrings state: directory mode: "0755" - name: Add Icinga apt signing key block: - name: Download Icinga signing key (ASCII-armored) get_url: url: "{{ icinga2_apt_key_url }}" dest: /tmp/icinga-key.asc mode: "0644" force: false - name: Convert key to binary format for apt shell: cmd: gpg --dearmor --yes -o "{{ icinga2_apt_keyring }}" /tmp/icinga-key.asc creates: "{{ icinga2_apt_keyring }}" - name: Set keyring permissions file: path: "{{ icinga2_apt_keyring }}" mode: "0644" - name: Remove auto-generated Icinga apt sources (conflict with our keyring path) ansible.builtin.file: path: "{{ item }}" state: absent loop: - /etc/apt/sources.list.d/jammy-icinga.list - /etc/apt/sources.list.d/jammy-icinga.list.distUpgrade - name: Add Icinga apt repository ansible.builtin.apt_repository: repo: "{{ icinga2_apt_repo }}" filename: icinga state: present update_cache: true - name: Install database stack ansible.builtin.apt: name: "{{ icinga2_db_packages }}" state: present update_cache: true - name: Install web stack ansible.builtin.apt: name: "{{ icinga2_web_packages }}" state: present - name: Install Icinga2 + Icinga Web 2 ansible.builtin.apt: name: "{{ icinga2_packages }}" state: present # ----------- PagerDuty agent ----------- - name: Add PagerDuty apt signing key block: - name: Download PagerDuty signing key (ASCII-armored) get_url: url: "{{ pdagent_apt_key_url }}" dest: /tmp/pdagent-key.asc mode: "0644" force: false - name: Convert key to binary format for apt shell: cmd: gpg --dearmor --yes -o "{{ pdagent_apt_keyring }}" /tmp/pdagent-key.asc creates: "{{ pdagent_apt_keyring }}" - name: Set keyring permissions file: path: "{{ pdagent_apt_keyring }}" mode: "0644" - name: Add PagerDuty apt repository ansible.builtin.apt_repository: repo: "{{ pdagent_apt_repo }}" filename: pdagent state: present update_cache: true - name: Install PagerDuty agent ansible.builtin.apt: name: "{{ pdagent_packages }}" state: present - name: Ensure PagerDuty agent is started + enabled ansible.builtin.systemd: name: pdagent state: started enabled: true - name: Ensure PHP MySQL extension matches Apache PHP version block: - name: Find Apache PHP version shell: cmd: a2query -m 2>/dev/null | grep -oP 'php\d+\.\d+' | head -1 executable: /bin/bash register: apache_php_version changed_when: false check_mode: false - name: Install MySQL module for Apache PHP apt: name: "{{ apache_php_version.stdout }}-mysql" state: present when: apache_php_version.stdout | length > 0 when: ansible_os_family == "Debian" - name: Ensure PyMySQL is installed (required by community.mysql) ansible.builtin.shell: cmd: | set -e if ! python3 -c "import pymysql" 2>/dev/null; then if ! command -v pip3 >/dev/null 2>&1; then python3 -c "import urllib.request; exec(urllib.request.urlopen('https://bootstrap.pypa.io/pip/get-pip.py').read())" fi pip3 install pymysql fi executable: /bin/bash register: pymysql_install changed_when: "'Successfully installed' in pymysql_install.stdout" # ----------- MariaDB ----------- - name: Ensure mariadb is started + enabled ansible.builtin.systemd: name: mariadb state: started enabled: true - name: Create IDO database community.mysql.mysql_db: name: "{{ icinga2_ido_db_name }}" state: present login_unix_socket: /run/mysqld/mysqld.sock - name: Create IDO daemon DB user (icinga2) community.mysql.mysql_user: name: "{{ icinga2_ido_db_user }}" host: localhost password: "{{ icinga2_ido_db_password }}" priv: "{{ icinga2_ido_db_name }}.*:ALL" state: present login_unix_socket: /run/mysqld/mysqld.sock - name: Create read-only IDO user for icingaweb2 (icinga) community.mysql.mysql_user: name: "{{ icingaweb2_ido_db_user }}" host: localhost password: "{{ icingaweb2_ido_db_password }}" priv: "{{ icingaweb2_ido_db_name }}.*:SELECT,SHOW VIEW" state: present login_unix_socket: /run/mysqld/mysqld.sock - name: Create icingaweb2 database community.mysql.mysql_db: name: "{{ icingaweb2_db_name }}" state: present login_unix_socket: /run/mysqld/mysqld.sock - name: Create icingaweb2 DB user community.mysql.mysql_user: name: "{{ icingaweb2_db_user }}" host: localhost password: "{{ icingaweb2_db_password }}" priv: "{{ icingaweb2_db_name }}.*:ALL" state: present login_unix_socket: /run/mysqld/mysqld.sock - name: Check whether IDO schema has been imported community.mysql.mysql_query: login_db: "{{ icinga2_ido_db_name }}" query: "SHOW TABLES LIKE 'icinga_dbversion'" login_unix_socket: /run/mysqld/mysqld.sock register: ido_schema_check changed_when: false - name: Import IDO schema (first install only) community.mysql.mysql_db: name: "{{ icinga2_ido_db_name }}" state: import target: "{{ icinga2_ido_schema_path }}" login_unix_socket: /run/mysqld/mysqld.sock when: ido_schema_check.rowcount[0] == 0 notify: Restart icinga2 - name: Check whether icingaweb2 schema has been imported community.mysql.mysql_query: login_db: "{{ icingaweb2_db_name }}" query: "SHOW TABLES LIKE 'icingaweb_user'" login_unix_socket: /run/mysqld/mysqld.sock register: iweb2_schema_check changed_when: false - name: Import icingaweb2 schema (first install only) community.mysql.mysql_db: name: "{{ icingaweb2_db_name }}" state: import target: /usr/share/icingaweb2/schema/mysql.schema.sql login_unix_socket: /run/mysqld/mysqld.sock when: iweb2_schema_check.rowcount[0] == 0 - name: Bootstrap icingaweb2 admin account (first install only) community.mysql.mysql_query: login_db: "{{ icingaweb2_db_name }}" query: >- INSERT INTO icingaweb_user (name, active, password_hash) VALUES (%(user)s, 1, %(hash)s) ON DUPLICATE KEY UPDATE password_hash = VALUES(password_hash) named_args: user: "{{ icingaweb2_admin_user }}" hash: "{{ icingaweb2_admin_password_hash }}" login_unix_socket: /run/mysqld/mysqld.sock when: - iweb2_schema_check.rowcount[0] == 0 - icingaweb2_admin_password_hash is defined # ----------- Icinga2 daemon config ----------- - name: Render icinga2.conf ansible.builtin.template: src: icinga2/icinga2.conf.j2 dest: /etc/icinga2/icinga2.conf owner: nagios group: nagios mode: "0640" notify: Restart icinga2 - name: Render constants.conf ansible.builtin.template: src: icinga2/constants.conf.j2 dest: /etc/icinga2/constants.conf owner: nagios group: nagios mode: "0640" notify: Restart icinga2 - name: Render zones.conf ansible.builtin.template: src: icinga2/zones.conf.j2 dest: /etc/icinga2/zones.conf owner: nagios group: nagios mode: "0640" notify: Restart icinga2 - name: Render features-available/ido-mysql.conf ansible.builtin.template: src: icinga2/features-available/ido-mysql.conf.j2 dest: /etc/icinga2/features-available/ido-mysql.conf owner: nagios group: nagios mode: "0640" notify: Restart icinga2 - name: Enable Icinga2 features ansible.builtin.file: src: "/etc/icinga2/features-available/{{ item }}.conf" dest: "/etc/icinga2/features-enabled/{{ item }}.conf" state: link force: true loop: "{{ icinga2_enabled_features }}" notify: Restart icinga2 # ----------- conf.d/ host + service definitions ----------- - name: Sync static conf.d files ansible.builtin.copy: src: icinga2/conf.d/ dest: /etc/icinga2/conf.d/ owner: nagios group: nagios mode: "0640" notify: Restart icinga2 - name: Render templated conf.d files (api-users + pagerduty) ansible.builtin.template: src: "icinga2/conf.d/{{ item }}.j2" dest: "/etc/icinga2/conf.d/{{ item }}" owner: nagios group: nagios mode: "0640" loop: - api-users.conf - pagerduty-icinga2.conf - pagerduty-servers-icinga2.conf notify: Restart icinga2 # ----------- Icinga Web 2 config ----------- - name: Sync icingaweb2 ini files (non-secret) ansible.builtin.copy: src: icingaweb2/ dest: /etc/icingaweb2/ owner: www-data group: icingaweb2 mode: "0660" directory_mode: "02770" notify: Reload apache2 - name: Render icingaweb2 resources.ini (DB credentials) ansible.builtin.template: src: icingaweb2/resources.ini.j2 dest: /etc/icingaweb2/resources.ini owner: www-data group: icingaweb2 mode: "0660" notify: Reload apache2 - name: Enable monitoring module ansible.builtin.file: src: /usr/share/icingaweb2/modules/monitoring dest: /etc/icingaweb2/enabledModules/monitoring state: link force: true notify: Reload apache2 # ----------- Apache ----------- - name: Enable apache modules required by icingaweb2 community.general.apache2_module: name: "{{ item }}" state: present loop: - rewrite - ssl notify: Restart apache2 - name: Ensure apache is started + enabled ansible.builtin.systemd: name: apache2 state: started enabled: true # ----------- Service start ----------- - name: Ensure icinga2 is started + enabled ansible.builtin.systemd: name: icinga2 state: started enabled: true