Add an RPZ blocklist on the Unbound resolvers that returns NXDOMAIN for a set of domains (and subdomains) and logs only those matches under rpz-log tag "blocklist". Domains are templated from resolver_blocked_domains (single source of truth) into /etc/unbound/blocklist.rpz; respip module enabled for RPZ support. Fix deprecation warnings across the Ansible tree: - apt_repository -> deb822_repository (monitor, aprsc, uisp, grafana), removing stale .list files and adding update_cache where deb822 drops it - community.mysql.* -> ansible.mysql.* (monitor) and requirements.yml - top-level facts -> ansible_facts[...] (ansible_os_family, distribution_release, fqdn, architecture, default_ipv4) repo-wide
372 lines
11 KiB
YAML
372 lines
11 KiB
YAML
---
|
|
# 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.deb822_repository:
|
|
name: icinga
|
|
types: [deb]
|
|
uris: https://packages.icinga.com/ubuntu
|
|
suites: "icinga-{{ ansible_facts['distribution_release'] }}"
|
|
components: [main]
|
|
signed_by: "{{ icinga2_apt_keyring }}"
|
|
state: present
|
|
|
|
- name: Remove legacy Icinga .list repo (superseded by deb822 .sources)
|
|
ansible.builtin.file:
|
|
path: /etc/apt/sources.list.d/icinga.list
|
|
state: absent
|
|
|
|
- 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.deb822_repository:
|
|
name: pdagent
|
|
types: [deb]
|
|
uris: https://packages.pagerduty.com/pdagent
|
|
suites: "deb/"
|
|
signed_by: "{{ pdagent_apt_keyring }}"
|
|
state: present
|
|
|
|
- name: Remove legacy PagerDuty .list repo (superseded by deb822 .sources)
|
|
ansible.builtin.file:
|
|
path: /etc/apt/sources.list.d/pdagent.list
|
|
state: absent
|
|
|
|
- name: Install PagerDuty agent
|
|
ansible.builtin.apt:
|
|
name: "{{ pdagent_packages }}"
|
|
state: present
|
|
update_cache: true
|
|
|
|
- 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_facts['os_family'] == "Debian"
|
|
|
|
- name: Ensure PyMySQL is installed (required by ansible.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
|
|
ansible.mysql.mysql_db:
|
|
name: "{{ icinga2_ido_db_name }}"
|
|
state: present
|
|
login_unix_socket: /run/mysqld/mysqld.sock
|
|
|
|
- name: Create IDO daemon DB user (icinga2)
|
|
ansible.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)
|
|
ansible.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
|
|
ansible.mysql.mysql_db:
|
|
name: "{{ icingaweb2_db_name }}"
|
|
state: present
|
|
login_unix_socket: /run/mysqld/mysqld.sock
|
|
|
|
- name: Create icingaweb2 DB user
|
|
ansible.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
|
|
ansible.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)
|
|
ansible.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
|
|
ansible.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)
|
|
ansible.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)
|
|
ansible.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
|