checkout with gigacoms

This commit is contained in:
mrwho 2026-05-08 22:25:29 +03:00
parent 1f4de8193f
commit f9712b45b0
100 changed files with 6502 additions and 623 deletions

21
.ansible-lint Normal file
View file

@ -0,0 +1,21 @@
---
profile: production
# Paths to exclude from linting
exclude_paths:
- collections/
- .git/
# Treat these rule IDs as warnings instead of errors
warn_list:
- experimental
- yaml[line-length]
- name
- no-handler
- risky-shell-pipe
- no-changed-when
- risky-file-permissions
# Skip rules that don't apply to this project
skip_list:
- var-naming[no-role-prefix]

View file

@ -1,12 +1,12 @@
[defaults] [defaults]
roles_path = roles roles_path = roles
collections_paths = collections collections_paths = collections
filter_plugins = filter_plugins
retry_files_enabled = False retry_files_enabled = False
#stdout_callback = yaml stdout_callback = yaml
bin_ansible_callbacks = True
interpreter_python = auto_silent interpreter_python = auto_silent
host_key_checking = False host_key_checking = False
deprecation_warnings = False deprecation_warnings=False
[ssh_connection] [ssh_connection]
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null

File diff suppressed because it is too large Load diff

Binary file not shown.

1
filter_plugins/ipaddr.py Normal file
View file

@ -0,0 +1 @@
from ansible_collections.ansible.utils.plugins.filter.ipaddr import FilterModule # noqa: F401

View file

@ -1,13 +1,37 @@
--- ---
# ── SSH connection ───────────────────────────────────────────────────────────── # ── SSH connection ─────────────────────────────────────────────────────────────
# Credentials are injected from GitLab CI/CD Variables: # Credentials are injected from GitLab CI/CD Variables:
# ANSIBLE_SSH_USER — remote user # ANSIBLE_SSH_USER — remote user
# ANSIBLE_SSH_PASS — remote user password # ANSIBLE_SSHKEY_ID_RSA — private SSH key (записывается в ~/.ssh/id_rsa в before_script)
# ANSIBLE_BECOME_PASS — sudo password (defaults to SSH password when not set) # ANSIBLE_BECOME_PASS — sudo password
ansible_user: "{{ lookup('env', 'ANSIBLE_SSH_USER') | mandatory }}" ansible_user: "{{ lookup('env', 'ANSIBLE_SSH_USER') | mandatory }}"
ansible_password: "{{ lookup('env', 'ANSIBLE_SSH_PASS') | mandatory }}"
ansible_become: true ansible_become: true
ansible_become_method: sudo ansible_become_method: sudo
ansible_become_pass: "{{ lookup('env', 'ANSIBLE_BECOME_PASS') | default(lookup('env', 'ANSIBLE_SSH_PASS'), true) }}" ansible_become_pass: "{{ lookup('env', 'ANSIBLE_BECOME_PASS') | mandatory }}"
ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
# Zabbix agent default settings
agent_major_version: "7.0"
agent_variant: "2"
agent_2_plugin_list: ['']
agent_param_server:
- 10.203.0.50
agent_param_serveractive:
- 10.203.0.50
agent_param_tlsconnect: unencrypted
agent_param_tlsaccept:
- unencrypted
# Chrony NTP Client settings
chrony_log_enable: true
chrony_log: measurements statistics tracking
chrony_logdir: /var/log/chrony/
chrony_ntp_servers:
- 10.203.2.11
- 10.203.2.12
chrony_rtcsync: true
chrony_timezone: Europe/Moscow
# Firewalld defaults
firewall_disable_conflicting_services: true
firewall_transactional_update_reboot_ok: true

View file

@ -0,0 +1,10 @@
---
# ── Rocky Linux 9 specifics ───────────────────────────────────────────────────
ansible_python_interpreter: /usr/bin/python3
# Группа для sudo-привилегий на RHEL-совместимых системах
users_sudo_group: wheel
# Переопределяем логику named-роли: RedHat.yml возвращает '2' для версий != 8,
# на Rocky 9 нужен python3-netaddr / python3-dns
named_python_version: "3"

View file

@ -0,0 +1,2 @@
# Нестандартный порт SSH
ansible_port: 3110

View file

@ -0,0 +1,3 @@
---
# MAC-адрес ens192 — используется в policy routing (CONNMARK по MAC)
nic_ens192_mac: "00:50:56:88:11:48"

View file

@ -0,0 +1,3 @@
---
# MAC-адрес ens192 — используется в policy routing (CONNMARK по MAC)
nic_ens192_mac: "00:50:56:88:66:23"

View file

@ -0,0 +1,32 @@
---
# ── SSH connection ─────────────────────────────────────────────────────────────
ansible_user: "{{ lookup('env', 'ANSIBLE_SSH_USER') | mandatory }}"
ansible_password: "{{ lookup('env', 'ANSIBLE_SSH_PASS') | mandatory }}"
ansible_become: true
ansible_become_method: sudo
ansible_become_pass: "{{ lookup('env', 'ANSIBLE_BECOME_PASS') | default(lookup('env', 'ANSIBLE_SSH_PASS'), true) }}"
ansible_ssh_common_args: "-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
# Zabbix Agent2
agent_major_version: "7.0"
agent_variant: "2"
agent_param_server:
- 10.203.0.50
agent_param_serveractive:
- 10.203.0.50
agent_param_listenport: 10050
# agent_2_plugin_list: ['named'] # set in inventory vars
agent_param_tlsconnect: unencrypted
agent_param_tlsaccept:
- unencrypted
# Chrony NTP Client settings
chrony_log_enable: true
chrony_log: measurements statistics tracking
chrony_logdir: /var/log/chrony/
chrony_ntp_servers:
- 10.203.2.11
- 10.203.2.12
chrony_rtcsync: true
chrony_timezone: Europe/Moscow

View file

@ -0,0 +1,3 @@
---
ansible_python_interpreter: /usr/bin/python3
users_sudo_group: wheel

43
inventory/test/hosts.yml Normal file
View file

@ -0,0 +1,43 @@
---
# Тестовый инвентарь для ветки a.kazantsev
# Используется в CI для syntax-check плейбуков, не входящих в prod-инвентарь
all:
children:
balancers:
hosts:
vm01-balancer:
rocky9:
hosts:
vm-akazantsev:
ansible_host: 10.203.0.105
ns1:
ansible_host: 10.203.2.11
agent_2_plugin_list: [named]
ns2:
ansible_host: 10.203.2.12
agent_2_plugin_list: [named]
vm01-balancer:
ansible_host: 10.203.2.21
agent_2_plugin_list: ['']
firewall_disable_conflicting_services: true
firewall_transactional_update_reboot_ok: true
vm-web:
ansible_host: 10.203.2.251
agent_2_plugin_list: ['']
firewall_disable_conflicting_services: true
firewall_transactional_update_reboot_ok: true
vm-radius:
ansible_host: 10.203.2.250
agent_2_plugin_list: ['']
firewall_disable_conflicting_services: true
firewall_transactional_update_reboot_ok: true
vm-zabbix:
ansible_host: 10.203.0.103
agent_2_plugin_list: ['']
firewall_disable_conflicting_services: true
firewall_transactional_update_reboot_ok: true
vm-zabbix-db:
ansible_host: 10.203.0.102
agent_2_plugin_list: ['']
firewall_disable_conflicting_services: true
firewall_transactional_update_reboot_ok: true

View file

@ -1,7 +1,7 @@
--- ---
- name: Install Chrony NTP Server - name: Install Chrony NTP Server
hosts: hosts:
- test - vm-zabbix
roles: roles:
- chrony - chrony
vars: vars:

569
playbooks/ns1.yml Normal file
View file

@ -0,0 +1,569 @@
---
- name: Configure named ns1
hosts: ns1
roles:
- routing-policy-dns-via-balancer
- named
vars:
policy_routing_local_routes:
- "10.203.2.0/24 dev ens192 scope link src {{ ansible_host }} metric 100"
policy_routing_balancers:
- ip: "{{ hostvars['vm01-balancer'].ansible_host }}"
mac: "{{ hostvars['vm01-balancer'].nic_ens192_mac }}"
table_id: 53
table_name: dns-via-vm01
fwmark: 53
- ip: "{{ hostvars['vm02-balancer'].ansible_host }}"
mac: "{{ hostvars['vm02-balancer'].nic_ens192_mac }}"
table_id: 54
table_name: dns-via-vm02
fwmark: 54
# Primary Configuration
named_listen_ipv4:
- "any"
named_listen_ipv4_port:
- 53
named_listen_ipv6:
- "::"
named_listen_ipv6_port:
- 53
named_recursion: true
named_allow_recursion:
- "Local"
named_allow_query:
- "any"
named_allow_transfer:
- "Transfer"
named_dns_keys:
- name: CertbotKey
algorithm: hmac-sha512
secret: "hbxr+SNi3kzzygeArFp/1xgribKLDLZEfRWWh/btH6jauMrcJ0oPyOEuP11d1Oq10HUJnTKnOtb8YlnxrM4HcA=="
named_extra_include_files:
- "{{ named_auth_file }}"
named_statistics_channels:
- named_statistics_host: '127.0.0.1'
- named_statistics_port: '8053'
- named_statistics_allow:
- '127.0.0.1'
named_acls:
- name: Transfer
match_list:
- 91.218.87.251
- 10.203.0.84
- 10.203.0.85
- 10.203.2.11
- 10.203.2.12
- name: Local
match_list:
- 127.0.0.1
- 127.0.0.0/8
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 100.64.0.0/10
- 91.218.84.0/22
- 91.236.140.0/22
- 91.197.57.0/24
- 213.109.201.0/24
- 46.255.25.0/24
- 2a13:af80::/29
named_zones:
# Primary server for domain gigacoms.info (specify zone type explicitly)
- name: 'gigacoms.info'
type: primary
certbot_key: "CerbotKey"
also_notify:
- 10.203.2.12
primaries:
- 10.203.2.11
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
# delegate:
# - zone: test.gigacoms.info.
# dns: ns3.gigacoms.info.
# - zone: test.gigacoms.info.
# dns: ns4.gigacoms.ru.
hosts:
- name: ns1
ip: 10.203.2.11
- name: ns2
ip: 91.218.87.251
- name: gitlab
ip: 91.218.87.197
# ipv6: 2001:db8::1
aliases:
- reg.gitlab
- pages.gitlab
- '*.pages.gitlab'
- name: minio
ip: 91.218.87.224
# ipv6: 2001:db8::2
aliases:
- registry
- kas
- name: tp.beta
ip: 10.201.0.6
# ipv6: 2001:db8::d:1
- name: vc1.beta
ip: 10.203.0.9
# ipv6: 2001:db8::d:2
- name: vctest.beta
ip: 10.203.0.13
# ipv6: 2001:db8::d:3
- name: hs001.beta
ip: 10.203.0.10
- name: hs002.beta
ip: 10.203.0.11
- name: hs003.beta
ip: 10.203.0.12
- name: db1.local
ip: 10.201.0.21
- name: db2.local
ip: 10.201.0.22
- name: dbpr.local
ip: 10.201.0.31
- name: nfs1.local
ip: 10.201.0.250
- name: node1.local
ip: 10.201.0.20
- name: node2.local
ip: 10.201.0.30
- name: vm-monitoring.local
ip: 10.201.0.2
- name: mskix-asbr-msk-m9-1
ip: 195.208.209.197
- name: mskix-asbr-msk-m9-2
ip: 195.208.209.77
- name: node1
ip: 91.218.87.220
- name: node2
ip: 91.218.87.230
- name: ns1
ip: 91.218.87.254
- name: ns2
ip: 91.218.87.251
- name: server-service-1
ip: 91.218.87.196
- name: ttk-asbr-modmd-1
ip: 217.150.46.25
- name: tn001
ip: 10.203.0.4
- name: default
ip: 91.218.87.224
- name: zabbix-db
ip: 10.203.0.51
- name: zabbix
ip: 10.203.0.50
- name: netbox
ip: 10.203.0.91
- name: br001
ip: 10.202.0.19
- name: skat-bras-1
ip: 10.203.0.252
- name: ldap
ip: 10.203.0.81
- name: dc1.smb
ip: 10.203.0.83
- name: br001.smb
ip: 10.202.0.19
- name: pale
ip: 10.203.0.83
- name: '*.d'
ip:
- 10.203.0.211
- 10.203.0.212
# mail_servers:
# - name: mail001
# preference: 10
# - name: mail002
# preference: 20
# services:
# - name: _ldap._tcp
# weight: 100
# port: 88
# target: srv010
# text:
# - name: _kerberos
# text: KERBEROS.ACME-INC.COM
# - name: '@'
# text:
# - 'some text'
# - 'more text'
- name: 'gigacoms.ru'
type: primary
certbot_key: "CerbotKey"
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
# networks:
# - '91.218.84'
# - '91.218.85'
# - '91.218.86'
# - '91.218.87'
# - '91.236.140'
# - '91.236.141'
# - '91.236.142'
# - '91.236.143'
# - '213.109.201'
# - '10.11'
# ipv6_networks:
# - '2001:db8::/48'
name_servers:
- ns1
- ns2
hosts:
- name: ns1
ip: 91.218.87.254
- name: ns2
ip: 91.218.87.251
- name: mail
alias: domain.mail.yandex.net.
- name: calendar
alias: ghs.google.com.
- name: corp
alias: ghs.google.com.
- name: docs
alias: ghs.google.com.
- name: podpiska
alias: showcase.rentsoft.ru.
- name: shop
alias: lb.bitrix24.shop.
- name: gigacoms.ru.
ip: 91.218.87.248
alias: www
- name: acs
ip: 10.1.1.70
- name: 2ip1
ip: 91.218.87.250
alias: 2ip2
- name: bill
ip: 91.218.87.225
- name: b2b
ip: 91.218.87.225
- name: crm
ip: 91.218.87.225
- name: hd
ip: 91.218.87.225
- name: hd-dev
ip: 91.218.87.225
- name: dev
ip: 91.218.87.225
- name: lora
ip: 91.218.87.225
- name: pg
ip: 91.218.87.225
- name: pulse
ip: 91.218.87.225
- name: report
ip: 91.218.87.225
- name: rkn
ip: 91.218.87.225
- name: us
ip: 91.218.87.225
- name: 24api
ip: 91.218.87.225
- name: vmmgr
ip: 91.218.87.225
- name: blmgr
ip: 91.218.87.225
- name: dcimgr
ip: 91.218.87.225
- name: logs
ip: 91.218.87.225
- name: grafana
ip: 91.218.87.225
- name: graylog
ip: 91.218.87.225
- name: okemerg
ip: 91.218.87.225
- name: portal
ip: 91.218.87.225
- name: fpst
ip: 91.218.87.202
- name: gate
ip: 91.218.87.205
- name: iot
ip: 91.218.87.198
- name: mon
ip: 91.218.87.196
- name: b24
ip: 91.218.87.249
- name: dev-b24
ip: 91.218.87.248
- name: service
ip: 91.218.87.250
- name: st1
ip: 91.218.87.250
- name: st2
ip: 91.218.87.250
- name: tvmw
ip: 91.218.87.203
- name: git
ip: 91.236.140.132
- name: node3
ip: 10.201.0.103
- name: vpn.office
ip: 91.218.87.205
- name: skat-bras-1
ip: 10.203.0.252
- name: skat-bras-2
ip: 10.203.0.251
- name: portainer
ip: 91.218.87.220
- name: gitlab
ip: 91.218.87.220
- name: semaphore
ip: 91.218.87.220
- name: nxmc
ip: 91.218.87.220
- name: zabbix
ip: 91.218.87.220
- name: genie
ip: 91.218.87.220
- name: ezdepot
ip: 91.218.87.220
- name: has
ip: 91.218.87.220
- name: probe
ip: 91.218.87.220
- name: miniui
ip: 91.218.87.220
- name: miniapi
ip: 91.218.87.220
mail_servers:
- name: mx.yandex.net.
preference: 10
# services:
# - name: _ldap._tcp
# weight: 100
# port: 88
# target: srv010
text:
- name: mail._domainkey
text: "v=DKIM1; k=rsa; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCngEizyzxPM785+q4dcj6MPKDsoTkP5DMzxptWso06+w+ROAxGX45ZijvGnQaA1WCKuATxr4kB0RvN6FGw8HpaNVPX7Odp8G8qkcNWCN4q4aHngQtoj5GMcwlR+Dvuv/AJ67VdL+9H/FxyJHR8ucje6MJzSYizxVpTNMyDF+lQZwIDAQAB"
- name: us._domainkey
text: "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRjOsvZZKZ/j3UhgVD+YwNftnSSXdWbqAf1QGz/IfvcvySKnrWzaaH2nSBYUXr2eiCzSuaJOwC8xnHcrfdSTBN3f4r+WqUcfTMdn5gROSn6TIg5bJMv+QFmo2b2kjOAgq7t+3yplKBneUnY8UXn33gt5EJ+ROVTYrL710nq4MbPwIDAQAB"
- name: '@'
text:
- "yandex-verification: 11bf6000ca841ac9"
- "v=spf1 include:_spf.yandex.net include:spf.unisender.com ~all"
- name: 'serverok.ru'
type: primary
certbot_key: "CerbotKey"
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
hosts:
- name: ns1
ip: 91.218.87.254
- name: ns2
ip: 91.218.87.251
- name: 'vermax.com'
type: primary
certbot_key: "CerbotKey"
primaries:
- 10.203.2.11
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
hosts:
- name: ns1
ip: 91.218.87.254
- name: ns2
ip: 91.218.87.251
- name: update
ip: 10.203.0.77
- name: '84.218.91.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '56'
ptr: 'mail.kotpilota.ru'
- name: '161'
ptr: 'smtp.gruzavto.net'
- name: '242'
ptr: 'exchange.freshsecret.ru'
- name: '85.218.91.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '55'
ptr: 'mx.wps.ru'
- name: '138'
ptr: 'mail.amazone.pro'
- name: '229'
ptr: 'billing.dnpveteran.ru'
- name: '86.218.91.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '149'
ptr: 'mail.d4t.ru'
- name: '184'
ptr: 'mx.huaxun.ru'
- name: '87.218.91.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '205'
ptr: 'gate.gigacoms.ru'
- name: '247'
ptr: 'ns1.gigacoms.info'
- name: '251'
ptr: 'ns2.gigacoms.ru'
- name: '251'
ptr: 'ns4.gigacoms.info'
- name: '254'
ptr: 'ns1.gigacoms.ru'
- name: '254'
ptr: 'ns3.gigacoms.info'
- name: '140.236.91.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '96/28.140.236.91.in-addr.arpa.'
dns: 'ns1.cittransm.ru.'
- name: '96/28.140.236.91.in-addr.arpa.'
dns: 'ns2.cittransm.ru.'
- name: '96/28.140.236.91.in-addr.arpa.'
dns: 'ns3.cittransm.ru.'
- name: '96'
cname: '96.96/28.140.236.91.in-addr.arpa.'
- name: '97'
cname: '97.96/28.140.236.91.in-addr.arpa.'
- name: '98'
cname: '98.96/28.140.236.91.in-addr.arpa.'
- name: '99'
cname: '99.96/28.140.236.91.in-addr.arpa.'
- name: '100'
cname: '100.96/28.140.236.91.in-addr.arpa.'
- name: '101'
cname: '101.96/28.140.236.91.in-addr.arpa.'
- name: '102'
cname: '102.96/28.140.236.91.in-addr.arpa.'
- name: '103'
cname: '103.96/28.140.236.91.in-addr.arpa.'
- name: '104'
cname: '104.96/28.140.236.91.in-addr.arpa.'
- name: '105'
cname: '105.96/28.140.236.91.in-addr.arpa.'
- name: '106'
cname: '106.96/28.140.236.91.in-addr.arpa.'
- name: '107'
cname: '107.96/28.140.236.91.in-addr.arpa.'
- name: '108'
cname: '108.96/28.140.236.91.in-addr.arpa.'
- name: '109'
cname: '109.96/28.140.236.91.in-addr.arpa.'
- name: '110'
cname: '110.96/28.140.236.91.in-addr.arpa.'
- name: '111'
cname: '111.96/28.140.236.91.in-addr.arpa.'
- name: '45'
ptr: 'mail.rst26.ru'
- name: '88'
ptr: 'ohana.msk.ru'
- name: '162'
ptr: 'gromakov.org'
- name: '168'
ptr: 'mail.roomika-mebel.ru'
- name: '141.236.91.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '89'
ptr: 'mail.geocaching.su'
- name: '201.109.213.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '166'
ptr: 'mx.gromakov.org'
- name: '203'
ptr: 'mail.testvia.ru'
- name: '0.203.10.in-addr.arpa'
type: primary
primaries:
- 10.203.2.11
also_notify:
- 10.203.2.12
name_servers:
- ns1.gigacoms.ru.
- ns2.gigacoms.ru.
reverse_zone: true
ptr_records:
- name: '9'
ptr: 'vc1.beta.gigacoms.info'
- name: '13'
ptr: 'vctest.beta.gigacoms.info'

View file

@ -2,9 +2,24 @@
- name: Configure named ns2 - name: Configure named ns2
hosts: ns2 hosts: ns2
roles: roles:
- routing-policy-dns-via-balancer
- named - named
vars: vars:
# Primary Configuration policy_routing_local_routes:
- "10.203.2.0/24 dev ens192 scope link src {{ ansible_host }} metric 100"
policy_routing_balancers:
- ip: "{{ hostvars['vm01-balancer'].ansible_host }}"
mac: "{{ hostvars['vm01-balancer'].nic_ens192_mac }}"
table_id: 53
table_name: dns-via-vm01
fwmark: 53
- ip: "{{ hostvars['vm02-balancer'].ansible_host }}"
mac: "{{ hostvars['vm02-balancer'].nic_ens192_mac }}"
table_id: 54
table_name: dns-via-vm02
fwmark: 54
# Secondary Configuration
named_listen_ipv4: named_listen_ipv4:
- "any" - "any"
named_listen_ipv4_port: named_listen_ipv4_port:

35
playbooks/postgresql.yml Normal file
View file

@ -0,0 +1,35 @@
---
- name: Install Postgresql
hosts: vm-zabbix-db
roles:
- postgresql
vars:
postgresql_enablerepo: "pgdg18"
# "https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm"
postgresql_version: "18"
timescaledb_enabled: true
postgresql_databases: []
# - name: exampledb # required; the rest are optional
# lc_collate: # defaults to 'en_US.UTF-8'
# lc_ctype: # defaults to 'en_US.UTF-8'
# encoding: # defaults to 'UTF-8'
# template: # defaults to 'template0'
# login_host: # defaults to 'localhost'
# login_password: # defaults to not set
# login_user: # defaults to '{{ postgresql_user }}'
# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
# port: # defaults to not set
# owner: # defaults to postgresql_user
# state: # defaults to 'present'
postgresql_users: []
# - name: jdoe #required; the rest are optional
# password: # defaults to not set
# encrypted: # defaults to not set
# role_attr_flags: # defaults to not set
# db: # defaults to not set
# login_host: # defaults to 'localhost'
# login_password: # defaults to not set
# login_user: # defaults to '{{ postgresql_user }}'
# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
# port: # defaults to not set
# state: # defaults to 'present'

226
playbooks/vm-balancer.yml Normal file
View file

@ -0,0 +1,226 @@
---
- name: Install balancer full
hosts:
- vm01-balancer
- vm02-balancer
roles:
- nginx
- zabbix-agent2
- firewall
- chrony
vars:
###### NGINX Configuration ######
nginx_worker_connections: 16384
nginx_use_epoll: true
nginx_multi_accept: "on"
nginx_selinux: false
pki_dir: /etc/nginx/certs
nginx_webroot: /var/www
local_http_port: 8080
nginx_letsencrypt_managed: true
letsencrypt_acme_install: true
letsencrypt_acme_certs_dir: /etc/letsencrypt/live
nginx_conf_snippets:
- nginx-compression.conf
- nginx-proxy-params.conf
- nginx-server-ssl.conf
# - nginx-websockets.conf
# - nginx-browser-cache.conf
# - letsencrypt-proxy.conf
# - nginx-cors.conf
nginx_streams:
- stream: DNS_udp
listen_port: 53
protocol: udp
transparent: true
responses: 1
timeout: 3s
backends:
- 10.203.2.11:53
- 10.203.2.12:53
- stream: DNS_tcp
listen_port: 53
protocol: tcp
transparent: true
responses: 1
timeout: 3s
backends:
- 10.203.2.11:53
- 10.203.2.12:53
- stream: NTP
listen_port: 123
protocol: udp
responses: 1
backends:
- 10.203.2.11:123
- 10.203.2.12:123
nginx_virthosts:
- virthost_name: gigacoms.ru
listen: "80"
server_name: gigacoms.ru
server_aliases: "www.gigacoms.ru"
# index: index.php
# error_page: /path_to_error_page.html
ssl_enabled: true
ssl_only: true
ssl_letsencrypt_certs: "{{ nginx_letsencrypt_managed }}"
# root: "{{ nginx_webroot }}"
server_tokens: "off"
proxy_standard_setup: true
proxy_additional_options:
- proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;
locations:
- location: /
target: "http://10.203.2.251:80"
###### Zabbix agent configuration ######
agent_package_state: present # present or latest
# agent_2_plugin_list: ['named'] # set in inventory vars
agent_apply_firewalld_rule: auto # force or auto
###### Firewalld configuration ######
firewall:
# - previous: replaced # flush previous rules
- zone: internal
state: enabled
permanent: true
service:
- ssh
- zabbix-agent
- ntp
- dns
- http
- https
port:
- '10050/tcp'
source:
- 10.200.0.0/16
- 10.202.0.0/16
- 10.203.0.0/16
- 91.218.87.192/26
- zone: internal
state: disabled
permanent: true
service:
- cockpit
- dhcpv6-client
- mdns
- samba-client
- zone: public
state: enabled
permanent: true
service:
- ntp
- dns
- http
- https
- zone: public
state: disabled
permanent: true
service:
- ssh
- cockpit
- dhcpv6-client
- mdns
- samba-client
- set_default_zone: internal
state: enabled
permanent: true
- interface: ens192
zone: internal
state: enabled
permanent: true
- interface: ens224
zone: public
state: enabled
permanent: true
###### chrony-client ######
chrony_disable_ntpd: true
chrony_enable: true
# Moved to inventory vars
handlers:
- name: Reload firewalld
ansible.builtin.service:
name: firewalld
state: reloaded
- name: Restart nginx-transparent-route
ansible.builtin.systemd:
name: nginx-transparent-route
state: restarted
daemon_reload: true
post_tasks:
- name: Включить ip_nonlocal_bind для transparent proxy
ansible.posix.sysctl:
name: net.ipv4.ip_nonlocal_bind
value: "1"
sysctl_file: /etc/sysctl.d/50-nginx-transparent.conf
reload: true
- name: Добавить таблицу 200 в rt_tables для local route
ansible.builtin.lineinfile:
path: /etc/iproute2/rt_tables
line: "200\tnginx-transparent"
regexp: "^200\\s"
owner: root
group: root
mode: "0644"
create: true
- name: Установить systemd unit nginx-transparent-route
ansible.builtin.copy:
dest: /etc/systemd/system/nginx-transparent-route.service
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Local route for nginx transparent proxy return path
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/ip rule add fwmark 100 table 200 priority 200
ExecStart=/usr/sbin/ip route add local 0.0.0.0/0 dev lo table 200
ExecStop=/usr/sbin/ip rule del fwmark 100 table 200 priority 200
ExecStop=/usr/sbin/ip route flush table 200
[Install]
WantedBy=multi-user.target
notify: Restart nginx-transparent-route
- name: Включить и запустить nginx-transparent-route
ansible.builtin.systemd:
name: nginx-transparent-route
enabled: true
state: started
daemon_reload: true
- name: Маркировать входящие DNS-ответы от бэкендов (PREROUTING)
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --add-rule
ipv4 mangle PREROUTING 0
-s 10.203.2.0/24 -p {{ item }} --sport 53
-j MARK --set-mark 100
loop:
- udp
- tcp
register: fwd_result
changed_when: "'ALREADY_ENABLED' not in fwd_result.stderr"
notify: Reload firewalld

View file

@ -68,13 +68,6 @@
- ipaddr: "0.0.0.0" - ipaddr: "0.0.0.0"
secret: radiussecpasw secret: radiussecpasw
radius_users: radius_users:
- user: test
password: 123
DlinkUserLevel: 5
DlinkPrivelegeLevel: 5
MikrotikGroup: full
ServiceType: 6
- user: 0dmin - user: 0dmin
password: "foot11foot" password: "foot11foot"
DlinkUserLevel: 5 DlinkUserLevel: 5

102
playbooks/vm-zabbix-db.yml Normal file
View file

@ -0,0 +1,102 @@
---
- name: Install zabbix-db
hosts:
- vm-zabbix-db
roles:
- postgresql
- firewall
- chrony
- zabbix-agent2
vars:
postgresql_enablerepo: "pgdg18"
# "https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm"
postgresql_version: "18"
timescaledb_enabled: true
postgresql_databases: []
# - name: exampledb # required; the rest are optional
# lc_collate: # defaults to 'en_US.UTF-8'
# lc_ctype: # defaults to 'en_US.UTF-8'
# encoding: # defaults to 'UTF-8'
# template: # defaults to 'template0'
# login_host: # defaults to 'localhost'
# login_password: # defaults to not set
# login_user: # defaults to '{{ postgresql_user }}'
# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
# port: # defaults to not set
# owner: # defaults to postgresql_user
# state: # defaults to 'present'
postgres_users_no_log: false
postgresql_users:
- name: zabbix
password: zabbixpw
db: zabbix
state: present
# - name: jdoe #required; the rest are optional
# password: # defaults to not set
# encrypted: # defaults to not set
# role_attr_flags: # defaults to not set
# db: # defaults to not set
# login_host: # defaults to 'localhost'
# login_password: # defaults to not set
# login_user: # defaults to '{{ postgresql_user }}'
# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
# port: # defaults to not set
# state: # defaults to 'present'
postgresql_hba_entries:
- type: host
database: all
user: all
address: 127.0.0.1/32
auth_method: trust
- type: host
database: all
user: all
address: localhost
auth_method: trust
- type: host
database: zabbix
user: zabbix
address: 10.203.0.50/32
auth_method: scram-sha-256
firewall:
# - previous: replaced # flush previous rules
- zone: internal
state: enabled
permanent: true
service:
- ssh
- zabbix-agent
- postgresql
source:
- 10.200.0.0/16
- 10.202.0.0/16
- 10.203.0.0/16
- 91.218.87.192/26
- zone: internal
state: disabled
permanent: true
service:
- cockpit
- dhcpv6-client
- mdns
- samba-client
- set_default_zone: internal
state: enabled
permanent: true
- interface: ens192
zone: internal
state: enabled
permanent: true
###### chrony-client ######
chrony_disable_ntpd: true
chrony_enable: true
###### Zabbix agent configuration ######
agent_package_state: present # present or latest
agent_2_plugin_list: ['postgresql']
agent_param_plugins_postgresql_system_path: /usr/sbin/zabbix-agent2-plugin/zabbix-agent2-plugin-postgresql

60
playbooks/vm-zabbix.yml Normal file
View file

@ -0,0 +1,60 @@
---
- name: Install zabbix
hosts:
- vm-zabbix
# - vm-zabbix-db
roles:
- firewall
- chrony
- zabbix-agent2
vars:
firewall:
# - previous: replaced # flush previous rules
- zone: internal
state: enabled
permanent: true
service:
- ssh
- zabbix-agent
- ntp
- dns
- http
- https
port:
- '10050/tcp'
- '8080/tcp'
- '3000/tcp'
source:
- 10.200.0.0/16
- 10.202.0.0/16
- 10.203.0.0/16
- 91.218.87.192/26
- zone: internal
state: disabled
permanent: true
service:
- cockpit
- dhcpv6-client
- mdns
- samba-client
- set_default_zone: internal
state: enabled
permanent: true
- interface: ens192
zone: internal
state: enabled
permanent: true
###### chrony-client ######
chrony_disable_ntpd: true
chrony_enable: true
# Moved to inventory vars
agent_package_state: present
agent_param_server:
- 127.0.0.1
agent_param_serveractive:
- 127.0.0.1

View file

@ -1,14 +1,17 @@
--- ---
- name: Install nginx - name: Install balancer full
hosts: vm01-balancer hosts: vm01-balancer
roles: roles:
- nginx - nginx
- zabbix-agent2 # - zabbix-agent2
- firewall - firewall
- chrony # - chrony
vars: vars:
###### NGINX Configuration ###### ###### NGINX Configuration ######
nginx_worker_connections: 16384
nginx_use_epoll: true
nginx_multi_accept: "on"
nginx_selinux: false nginx_selinux: false
pki_dir: /etc/nginx/certs pki_dir: /etc/nginx/certs
nginx_webroot: /var/www nginx_webroot: /var/www
@ -26,15 +29,28 @@
# - nginx-cors.conf # - nginx-cors.conf
nginx_streams: nginx_streams:
- stream: DNS - stream: DNS_udp
listen_port: 53 listen_port: 53
protocol: udp protocol: udp
transparent: true
responses: 1
timeout: 3
backends:
- 10.203.2.11:53
- 10.203.2.12:53
- stream: DNS_tcp
listen_port: 53
protocol: tcp
transparent: true
responses: 1
backends: backends:
- 10.203.2.11:53 - 10.203.2.11:53
- 10.203.2.12:53 - 10.203.2.12:53
- stream: NTP - stream: NTP
listen_port: 123 listen_port: 123
protocol: udp protocol: udp
responses: 1
timeout: 3
backends: backends:
- 10.203.2.11:123 - 10.203.2.11:123
- 10.203.2.12:123 - 10.203.2.12:123
@ -72,7 +88,7 @@
###### Firewalld configuration ###### ###### Firewalld configuration ######
firewall: firewall:
- previous: replaced # - previous: replaced # flush previous rules
- zone: internal - zone: internal
state: enabled state: enabled
@ -87,9 +103,10 @@
port: port:
- '10050/tcp' - '10050/tcp'
source: source:
- 10.0.0.0/8 - 10.200.0.0/16
- 172.16.0.0/12 - 10.202.0.0/16
- 192.168.0.0/16 - 10.203.0.0/16
- 91.218.87.192/26
- zone: internal - zone: internal
state: disabled state: disabled
@ -108,8 +125,6 @@
- dns - dns
- http - http
- https - https
# forward_port:
# - '53/udp;;10.203.2.11'
- zone: public - zone: public
state: disabled state: disabled
@ -146,3 +161,78 @@
- 10.203.2.12 - 10.203.2.12
chrony_rtcsync: true chrony_rtcsync: true
chrony_timezone: Europe/Moscow chrony_timezone: Europe/Moscow
handlers:
- name: Reload firewalld
ansible.builtin.service:
name: firewalld
state: reloaded
- name: Restart nginx-transparent-route
ansible.builtin.systemd:
name: nginx-transparent-route
state: restarted
daemon_reload: true
post_tasks:
- name: Включить ip_nonlocal_bind для transparent proxy
ansible.posix.sysctl:
name: net.ipv4.ip_nonlocal_bind
value: "1"
sysctl_file: /etc/sysctl.d/50-nginx-transparent.conf
reload: true
- name: Добавить таблицу 200 в rt_tables для local route
ansible.builtin.lineinfile:
path: /etc/iproute2/rt_tables
line: "200\tnginx-transparent"
regexp: "^200\\s"
owner: root
group: root
mode: "0644"
create: true
- name: Установить systemd unit nginx-transparent-route
ansible.builtin.copy:
dest: /etc/systemd/system/nginx-transparent-route.service
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Local route for nginx transparent proxy return path
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/ip rule add fwmark 100 table 200 priority 200
ExecStart=/usr/sbin/ip route add local 0.0.0.0/0 dev lo table 200
ExecStop=/usr/sbin/ip rule del fwmark 100 table 200 priority 200
ExecStop=/usr/sbin/ip route flush table 200
[Install]
WantedBy=multi-user.target
notify: Restart nginx-transparent-route
- name: Включить и запустить nginx-transparent-route
ansible.builtin.systemd:
name: nginx-transparent-route
enabled: true
state: started
daemon_reload: true
- name: Маркировать входящие DNS-ответы от бэкендов (PREROUTING)
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --add-rule
ipv4 mangle PREROUTING 0
-s 10.203.2.0/24 -p {{ item }} --sport 53
-j MARK --set-mark 100
loop:
- udp
- tcp
register: fwd_result
changed_when: "'ALREADY_ENABLED' not in fwd_result.stderr"
notify: Reload firewalld

236
playbooks/vm02-balancer.yml Normal file
View file

@ -0,0 +1,236 @@
---
- name: Install balancer full
hosts: vm02-balancer
roles:
- nginx
# - zabbix-agent2
- firewall
# - chrony
vars:
###### NGINX Configuration ######
nginx_worker_connections: 16384
nginx_use_epoll: true
nginx_multi_accept: "on"
nginx_selinux: false
pki_dir: /etc/nginx/certs
nginx_webroot: /var/www
local_http_port: 8080
nginx_letsencrypt_managed: true
letsencrypt_acme_install: true
letsencrypt_acme_certs_dir: /etc/letsencrypt/live
nginx_conf_snippets:
- nginx-compression.conf
- nginx-proxy-params.conf
- nginx-server-ssl.conf
# - nginx-websockets.conf
# - nginx-browser-cache.conf
# - letsencrypt-proxy.conf
# - nginx-cors.conf
nginx_streams:
- stream: DNS_udp
listen_port: 53
protocol: udp
transparent: true
responses: 1
backends:
- 10.203.2.11:53
- 10.203.2.12:53
- stream: DNS_tcp
listen_port: 53
protocol: tcp
transparent: true
responses: 1
backends:
- 10.203.2.11:53
- 10.203.2.12:53
- stream: NTP
listen_port: 123
protocol: udp
responses: 1
backends:
- 10.203.2.11:123
- 10.203.2.12:123
nginx_virthosts:
- virthost_name: gigacoms.ru
listen: "80"
server_name: gigacoms.ru
server_aliases: "www.gigacoms.ru"
# index: index.php
# error_page: /path_to_error_page.html
ssl_enabled: true
ssl_only: true
ssl_letsencrypt_certs: "{{ nginx_letsencrypt_managed }}"
# root: "{{ nginx_webroot }}"
server_tokens: "off"
proxy_standard_setup: true
proxy_additional_options:
- proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=cache:30m max_size=250m;
locations:
- location: /
target: "http://10.203.2.251:80"
###### Zabbix agent configuration ######
agent_major_version: "7.0"
agent_variant: "2"
agent_package_state: present # present or latest
agent_param_server: ::/0
agent_param_listenport: 10050
# agent_2_plugin_list: ['named'] # set in inventory vars
agent_param_tlsconnect: unencrypted
agent_param_tlsaccept:
- unencrypted
agent_apply_firewalld_rule: auto # force or auto
###### Firewalld configuration ######
firewall:
# - previous: replaced # flush previous rules
- zone: internal
state: enabled
permanent: true
service:
- ssh
- zabbix-agent
- ntp
- dns
- http
- https
port:
- '10050/tcp'
source:
- 10.200.0.0/16
- 10.202.0.0/16
- 10.203.0.0/16
- 91.218.87.192/26
- zone: internal
state: disabled
permanent: true
service:
- cockpit
- dhcpv6-client
- mdns
- samba-client
- zone: public
state: enabled
permanent: true
service:
- ntp
- dns
- http
- https
- zone: public
state: disabled
permanent: true
service:
- ssh
- cockpit
- dhcpv6-client
- mdns
- samba-client
- set_default_zone: internal
state: enabled
permanent: true
- interface: ens192
zone: internal
state: enabled
permanent: true
- interface: ens224
zone: public
state: enabled
permanent: true
###### chrony-client ######
chrony_disable_ntpd: true
chrony_enable: true
chrony_log_enable: true
chrony_log: measurements statistics tracking
chrony_logdir: /var/log/chrony/
chrony_ntp_servers:
- 10.203.2.11
- 10.203.2.12
chrony_rtcsync: true
chrony_timezone: Europe/Moscow
handlers:
- name: Reload firewalld
ansible.builtin.service:
name: firewalld
state: reloaded
- name: Restart nginx-transparent-route
ansible.builtin.systemd:
name: nginx-transparent-route
state: restarted
daemon_reload: true
post_tasks:
- name: Включить ip_nonlocal_bind для transparent proxy
ansible.posix.sysctl:
name: net.ipv4.ip_nonlocal_bind
value: "1"
sysctl_file: /etc/sysctl.d/50-nginx-transparent.conf
reload: true
- name: Добавить таблицу 200 в rt_tables для local route
ansible.builtin.lineinfile:
path: /etc/iproute2/rt_tables
line: "200\tnginx-transparent"
regexp: "^200\\s"
owner: root
group: root
mode: "0644"
create: true
- name: Установить systemd unit nginx-transparent-route
ansible.builtin.copy:
dest: /etc/systemd/system/nginx-transparent-route.service
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Local route for nginx transparent proxy return path
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/ip rule add fwmark 100 table 200 priority 200
ExecStart=/usr/sbin/ip route add local 0.0.0.0/0 dev lo table 200
ExecStop=/usr/sbin/ip rule del fwmark 100 table 200 priority 200
ExecStop=/usr/sbin/ip route flush table 200
[Install]
WantedBy=multi-user.target
notify: Restart nginx-transparent-route
- name: Включить и запустить nginx-transparent-route
ansible.builtin.systemd:
name: nginx-transparent-route
enabled: true
state: started
daemon_reload: true
- name: Маркировать входящие DNS-ответы от бэкендов (PREROUTING)
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --add-rule
ipv4 mangle PREROUTING 0
-s 10.203.2.0/24 -p {{ item }} --sport 53
-j MARK --set-mark 100
loop:
- udp
- tcp
register: fwd_result
changed_when: "'ALREADY_ENABLED' not in fwd_result.stderr"
notify: Reload firewalld

View file

@ -10,7 +10,11 @@
agent_major_version: "7.0" agent_major_version: "7.0"
agent_variant: "2" agent_variant: "2"
agent_package_state: present # present or latest agent_package_state: present # present or latest
agent_param_server: ::/0 agent_param_server:
- 10.203.0.50
agent_param_serveractive:
- 127.0.0.1
- 10.203.0.50
agent_param_listenport: 10050 agent_param_listenport: 10050
# agent_2_plugin_list: ['named'] # set in inventory vars # agent_2_plugin_list: ['named'] # set in inventory vars
agent_param_tlsconnect: unencrypted agent_param_tlsconnect: unencrypted

View file

@ -2,8 +2,9 @@
collections: collections:
- name: ansible.posix - name: ansible.posix
version: ">=1.5.0" version: ">=1.5.0"
- name: ansible.utils
version: ">=2.0.0,<5.0.0"
- name: community.general - name: community.general
version: ">=8.0.0" version: ">=8.0.0"
- name: community.vmware - name: community.vmware
version: ">=4.0.0" version: ">=4.0.0"
- name: ansible.netcommon

215
roles/firewall/README.md Normal file
View file

@ -0,0 +1,215 @@
# Роль `firewall`
Ansible-роль для управления firewalld на Linux-серверах. Основана на [linux-system-roles/firewall](https://github.com/linux-system-roles/firewall). Устанавливает firewalld, отключает конкурирующие сервисы и применяет конфигурацию зон, сервисов, портов, правил и интерфейсов через встроенный модуль `firewall_lib`.
## Поддерживаемые платформы
- RHEL / CentOS / AlmaLinux / Rocky Linux 7, 8, 9
- Fedora
- SLES 15
## Требования
- systemd
- Python 3 на управляемом узле
- Для EL7: пакеты `NetworkManager` и `python-ipaddress` (устанавливаются ролью автоматически)
## Переменные роли
| Переменная | Тип | Умолчание | Описание |
|---|---|---|---|
| `firewall` | list / map | `[]` | Список объектов конфигурации firewalld (см. ниже) |
| `firewall_disable_conflicting_services` | bool | `false` | Остановить и отключить `nftables`, `iptables`, `ufw` при наличии |
| `firewall_transactional_update_reboot_ok` | bool / null | `null` | Разрешить автоматическую перезагрузку на transactional-update системах (SLES) |
## Структура переменной `firewall`
Переменная `firewall` — список объектов. Каждый объект описывает одно или несколько действий с firewalld. Поля могут комбинироваться в одном объекте.
### Управление зонами и сервисами
```yaml
firewall:
- zone: internal
state: enabled # enabled / disabled / present / absent
permanent: true
service:
- ssh
- http
- https
port:
- '8080/tcp'
- '9090/tcp'
source:
- 10.0.0.0/8
- 192.168.0.0/16
```
### Привязка интерфейса к зоне
```yaml
firewall:
- interface: ens192
zone: internal
state: enabled
permanent: true
```
### Смена зоны по умолчанию
```yaml
firewall:
- set_default_zone: internal
state: enabled
permanent: true
```
### Проброс портов (DNAT)
```yaml
firewall:
- zone: public
forward_port:
- port: 8080
proto: tcp
toport: 80
toaddr: 192.168.1.10
state: enabled
permanent: true
```
### Маскарадинг
```yaml
firewall:
- zone: external
masquerade: true
state: enabled
permanent: true
```
### Rich rules
```yaml
firewall:
- zone: public
rich_rule: 'rule family="ipv4" source address="1.2.3.4" drop'
state: enabled
permanent: true
```
### Управление ipset
```yaml
firewall:
- ipset: blocklist
ipset_type: hash:ip
ipset_entries:
- 1.2.3.4
- 5.6.7.8
state: enabled
permanent: true
```
### Сброс к заводским настройкам
```yaml
firewall:
- previous: replaced
```
Удаляет всю кастомную конфигурацию перед применением новых правил.
## Сбор фактов
Если переменная `firewall` не задана или пуста, роль сохраняет текущую конфигурацию firewalld в факт `firewall_config`.
Для подробного вывода:
```yaml
firewall:
- detailed: true
```
## Пример использования (из vm01-balancer.yml / vm02-balancer.yml)
```yaml
- name: Настройка балансировщика
hosts: vm01-balancer
roles:
- firewall
vars:
firewall_disable_conflicting_services: true
firewall_transactional_update_reboot_ok: true
firewall:
- zone: internal
state: enabled
permanent: true
service:
- ssh
- zabbix-agent
- ntp
- dns
- http
- https
port:
- '10050/tcp'
source:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- zone: internal
state: disabled
permanent: true
service:
- cockpit
- dhcpv6-client
- mdns
- samba-client
- zone: public
state: enabled
permanent: true
service:
- ntp
- dns
- http
- https
- zone: public
state: disabled
permanent: true
service:
- ssh
- cockpit
- dhcpv6-client
- mdns
- samba-client
- set_default_zone: internal
state: enabled
permanent: true
- interface: ens192
zone: internal
state: enabled
permanent: true
- interface: ens224
zone: public
state: enabled
permanent: true
```
## Внутреннее устройство
Основная логика реализована в `library/firewall_lib.py` — кастомном Ansible-модуле с тремя бэкендами:
- **OnlineAPIBackend** — взаимодействие с работающим firewalld через D-Bus
- **InMemoryBackend** — генерация diff без изменений (для `--check`/`--diff` режимов)
- **OfflineCLIBackend** — использует `firewall-offline-cmd` (для сборки контейнеров)
Факты собираются через отдельный модуль `library/firewall_lib_facts.py`.

View file

@ -334,127 +334,6 @@ molecule/shared_inventory
... ...
``` ```
## Testing
This role is tested using [Ansible Molecule](https://molecule.readthedocs.io/). Tests are launched automatically on [Github Actions](https://github.com/bertvv/ansible-role-bind/actions) after each commit and PR.
This Molecule configuration will:
- Run Yamllint and Ansible Lint
- Create three Docker containers, one primary (`ns1`), one secondary (`ns2`) DNS server and forwarder(`ns3`) - `default` molecule scenario
- Run a syntax check
- Apply the role with a [test playbook](molecule/default/converge.yml) and check idempotence
- Run acceptance tests with [verify playbook](molecule/default/verify.yml)
- Create two additional Docker containers, one primary(`ns4`) and one secondary (`ns5`) and run `shared_inventory` scenario
This process is repeated for all the supported Linux distributions.
### Local test environment
In order to run the acceptance tests on this role locally, you can install the necessary tools on your machine, or use this reproducible setup in a VirtualBox VM (set up with Vagrant): <https://github.com/bertvv/ansible-testenv>.
Steps to install the tools manually:
1. Docker should be installed on your machine
2. As recommended by Molecule, create a python virtual environment
3. Install the software tools `python3 -m pip install molecule molecule-docker docker netaddr dnspython yamllint ansible-lint`
4. Navigate to the root of the role directory and run `molecule test`
Molecule automatically deletes the containers after a test. If you would like to check out the containers yourself, run `molecule converge` followed by `molecule login --host HOSTNAME`.
The Docker containers are based on images created by [Jeff Geerling](https://hub.docker.com/u/geerlingguy), specifically for Ansible testing (look for images named `geerlingguy/docker-DISTRO-ansible`). You can use any of his images, but only the distributions mentioned in [meta/main.yml](meta/main.yml) are supported.
The default config will start three Centos 8 containers (the primary supported platform at this time). Choose another distro by setting the `MOLECULE_DISTRO` variable with the command, e.g.:
``` bash
MOLECULE_DISTRO=debian9 molecule test
```
or
``` bash
MOLECULE_DISTRO=debian9 molecule converge
```
You can run the acceptance tests on all servers with `molecule verify`.
> Verification tests are done using "dig" lookup module by quering dns records and validating responses. This requires direct network communication between Ansible controller node (your machine running Ansible) and the target docker container.
--- ---
**NOTE**
Molecule verify tests will fail if docker is running on MacOS, as MacOS cannot access container IP directly. This is a known issue. See [#2670](https://github.com/docker/for-mac/issues/2670).
Workaround:
1. Run molecule linter: `molecule lint`
2. Provision containers: `molecule converge`
3. Connect to container: `molecule login --host ns1`
4. Go to role directory: `cd /etc/ansible/roles/bertvv.bind`
5. Run verify playbook:
```console
ansible-playbook -c local -i "`hostname`," -i molecule/default/inventory.ini molecule/default/verify.yml
```
6. Repeat steps 2-4 for `ns2` and `ns3`
---
## License
BSD
## Contributors
This role could only have been realized thanks to the contributions of many. If you have an idea to improve it even further, don't hesitate to pitch in!
Issues, feature requests, ideas, suggestions, etc. can be posted in the Issues section.
Pull requests are also very welcome. Please create a topic branch for your proposed changes. If you don't, this will create conflicts in your fork after the merge. Don't hesitate to add yourself to the contributor list below in your PR!
Maintainers:
- [Bert Van Vreckem](https://github.com/bertvv/)
- [Gregory Shulov](https://github.com/GR360RY)
- [Stuart Knight](https://github.com/blofeldthefish)
Contributors:
- [Aido](https://github.com/aido)
- [Angel Barrera](https://github.com/angelbarrera92)
- [B. Verschueren](https://github.com/bverschueren)
- [Boris Momčilović](https://github.com/kornrunner)
- [Brad Durrow](https://github.com/bdurrow)
- [Christopher Hicks](http://www.chicks.net/)
- [David J. Haines](https://github.com/dhaines)
- [Fabio Rocha](https://github.com/frock81)
- [Fazle Arefin](https://github.com/fazlearefin)
- [flora-five](https://github.com/flora-five)
- [Greg Cockburn](https://github.com/gergnz)
- [Guillaume Darmont](https://github.com/gdarmont)
- [itbane](https://github.com/itbane)
- [jadjay](https://github.com/jadjay)
- [Jascha Sticher](https://github.com/itbane)
- [Joanna Delaporte](https://github.com/jdelaporte)
- [Jörg Eichhorn](https://github.com/jeichhorn)
- [Jose Taas](https://github.com/josetaas)
- [Lennart Weller](https://github.com/lhw)
- [Loic Dachary](http://dachary.org)
- [Mario Ciccarelli](https://github.com/kartone)
- [Miroslav Hudec](https://github.com/mihudec)
- [Otto Sabart](https://github.com/seberm)
- [Paulius Mazeika](https://github.com/pauliusm)
- [Paulo E. Castro](https://github.com/pecastro)
- [Peter Janes](https://github.com/peterjanes)
- [psa](https://github.com/psa)
- [Rafael Bodill](https://github.com/rafi)
- [Rayford Johnson](https://github.com/rayfordj)
- [Robin Ophalvens](https://github.com/RobinOphalvens)
- [Romuald](https://github.com/rds13)
- [roumano](https://github.com/roumano)
- [Shawn Wilsher](https://github.com/sdwilsh)
- [Tom Meinlschmidt](https://github.com/tmeinlschmidt)
- [Jascha Sticher](https://github.com/itbane)
- [Zephyr82](https://github.com/Zephyr82)

View file

@ -116,10 +116,9 @@
become: true become: true
tags: bind tags: bind
# - name: Permit DNS traffic in firewalld - name: Permit DNS traffic in firewalld
# ansible.posix.firewalld: ansible.posix.firewalld:
# service: dns service: dns
# permanent: true permanent: true
# state: enabled state: enabled
# immediate: true immediate: true
# when: named_firewalld_enable is defined

View file

@ -39,6 +39,7 @@ nginx_conf_remote_global_conf: []
nginx_workers: 4 nginx_workers: 4
nginx_worker_connections: 1024 nginx_worker_connections: 1024
nginx_multi_accept: "off" nginx_multi_accept: "off"
nginx_use_epoll: false
nginx_worker_rlimit_nofile: 2048 nginx_worker_rlimit_nofile: 2048
nginx_server_tokens: "off" nginx_server_tokens: "off"
nginx_server_names_hash_bucket_size: 64 nginx_server_names_hash_bucket_size: 64

View file

@ -8,3 +8,8 @@
ansible.builtin.service: ansible.builtin.service:
name: nginx name: nginx
state: restarted state: restarted
- name: Daemon reload
ansible.builtin.service:
name: nginx
daemon_reload: true

View file

@ -13,11 +13,11 @@
- name: Configure VHosts - name: Configure VHosts
ansible.builtin.import_tasks: nginx-virtualhosts.yml ansible.builtin.import_tasks: nginx-virtualhosts.yml
# when: nginx_virthosts is defined # when: nginx_virthosts is defined
when: nginx_virthosts | length when: nginx_virthosts | length > 0
- name: Configure streams - name: Configure streams
ansible.builtin.import_tasks: nginx-stream.yml ansible.builtin.import_tasks: nginx-stream.yml
when: nginx_streams | length when: nginx_streams | length > 0
- name: Generate robots.txt - name: Generate robots.txt
ansible.builtin.import_tasks: robots-txt.yml ansible.builtin.import_tasks: robots-txt.yml

View file

@ -138,6 +138,27 @@
mode: "0444" mode: "0444"
notify: Reload nginx notify: Reload nginx
- name: Install Statistics stub
ansible.builtin.template:
src: nginx-stub.conf.j2
dest: /etc/nginx/conf.d/nginx-stats.conf
mode: "0444"
- name: Создать директорию для systemd override nginx
ansible.builtin.file:
path: /etc/systemd/system/nginx.service.d
state: directory
when: nginx_streams | default([]) | selectattr('transparent', 'defined') | selectattr('transparent') | list | length > 0
- name: Systemd override для nginx — CAP_NET_RAW (transparent proxy)
ansible.builtin.template:
src: nginx-systemd-override.j2
dest: /etc/systemd/system/nginx.service.d/transparent.conf
when: nginx_streams | default([]) | selectattr('transparent', 'defined') | selectattr('transparent') | list | length > 0
notify:
- Daemon reload
- Restart nginx
- name: Disable nginx - name: Disable nginx
when: when:
- nginx_enabled - nginx_enabled

View file

@ -31,7 +31,7 @@
loop: "{{ nginx_virthosts }}" loop: "{{ nginx_virthosts }}"
notify: Reload nginx notify: Reload nginx
#- name: Create vhosts dirs # - name: Create vhosts dirs
# tags: [nginx, virtualhost] # tags: [nginx, virtualhost]
# ansible.builtin.file: # ansible.builtin.file:
# path: "{{ item.root }}" # path: "{{ item.root }}"

View file

@ -10,11 +10,16 @@ upstream {{ item.stream }}_backend {
server { server {
listen {{ item.listen_port }}{% if item.protocol == 'udp' %} udp{% endif %}; listen {{ item.listen_port }}{% if item.protocol == 'udp' %} udp{% endif %};
proxy_pass {{ item.stream }}_backend; proxy_pass {{ item.stream }}_backend;
{% if item.transparent | default(false) %}
proxy_bind $remote_addr transparent;
{% endif %}
{% if item.responses is defined %}
proxy_responses {{ item.responses }};
{% endif %}
{% if item.timeout is defined %} {% if item.timeout is defined %}
proxy_timeout {{ item.timeout }}; proxy_timeout {{ item.timeout }};
{% endif %} {% endif %}
{%- if item.connect_timeout is defined %} {%- if item.connect_timeout is defined %}
proxy_connect_timeout {{ item.connect_timeout }}; proxy_connect_timeout {{ item.connect_timeout }};
{% endif %} {% endif %}
} }

View file

@ -0,0 +1,12 @@
server {
listen 127.0.0.1:8080;
server_name localhost;
keepalive_timeout 0;
allow 127.0.0.1;
deny all;
server_tokens on;
location /server-status {
stub_status on;
}
access_log off;
}

View file

@ -0,0 +1,3 @@
[Service]
LimitNOFILE=524288
AmbientCapabilities=CAP_NET_RAW CAP_NET_BIND_SERVICE

View file

@ -19,6 +19,9 @@ include /usr/share/nginx/modules/*.conf;
events { events {
worker_connections {{ nginx_worker_connections }}; worker_connections {{ nginx_worker_connections }};
{% if nginx_use_epoll %}
use epoll;
{% endif %}
multi_accept {{ nginx_multi_accept }}; multi_accept {{ nginx_multi_accept }};
} }
worker_rlimit_nofile {{ nginx_worker_rlimit_nofile }}; worker_rlimit_nofile {{ nginx_worker_rlimit_nofile }};

View file

@ -1,13 +1,13 @@
--- ---
- name: restart webserver - name: Restart webserver
service: ansible.builtin.service:
name: "{{ php_webserver_daemon }}" name: "{{ php_webserver_daemon }}"
state: restarted state: restarted
notify: restart php-fpm notify: Restart php-fpm
when: php_enable_webserver when: php_enable_webserver
- name: restart php-fpm - name: Restart php-fpm
service: ansible.builtin.service:
name: "{{ php_fpm_daemon }}" name: "{{ php_fpm_daemon }}"
state: "{{ php_fpm_handler_state }}" state: "{{ php_fpm_handler_state }}"
when: when:

View file

@ -1,37 +1,37 @@
--- ---
- name: Check for existing APCu config files. - name: Check for existing APCu config files.
find: ansible.builtin.find:
paths: "{{ item }}" paths: "{{ item }}"
contains: 'extension(\s+)?=(\s+)?apc[u]?\.so' contains: 'extension(\s+)?=(\s+)?apc[u]?\.so'
register: php_installed_apc_confs register: php_installed_apc_confs
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
- name: Remove any non-role-supplied APCu config files. - name: Remove any non-role-supplied APCu config files.
file: ansible.builtin.file:
path: "{{ item.1.path }}" path: "{{ item.1.path }}"
state: absent state: absent
when: php_apc_conf_filename != (item.1.path.split('/') | last) when: php_apc_conf_filename != (item.1.path.split('/') | last)
with_subelements: with_subelements:
- "{{ php_installed_apc_confs.results }}" - "{{ php_installed_apc_confs.results }}"
- files - files
notify: restart webserver notify: Restart webserver
- name: Ensure APCu config file is present. - name: Ensure APCu config file is present.
template: ansible.builtin.template:
src: apc.ini.j2 src: apc.ini.j2
dest: "{{ item }}/{{ php_apc_conf_filename }}" dest: "{{ item }}/{{ php_apc_conf_filename }}"
owner: root owner: root
group: root group: root
force: true force: true
mode: 0644 mode: '0644'
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
when: php_enable_apc when: php_enable_apc
notify: restart webserver notify: Restart webserver
- name: Remove APCu config file if APC is disabled. - name: Remove APCu config file if APC is disabled.
file: ansible.builtin.file:
path: "{{ item }}/{{ php_apc_conf_filename }}" path: "{{ item }}/{{ php_apc_conf_filename }}"
state: absent state: absent
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
when: not php_enable_apc when: not php_enable_apc
notify: restart webserver notify: Restart webserver

View file

@ -1,52 +1,52 @@
--- ---
- name: Define php_fpm_daemon. - name: Define php_fpm_daemon.
set_fact: ansible.builtin.set_fact:
php_fpm_daemon: "{{ __php_fpm_daemon }}" php_fpm_daemon: "{{ __php_fpm_daemon }}"
when: php_fpm_daemon is not defined when: php_fpm_daemon is not defined
- name: Define php_fpm_pool_conf_path. - name: Define php_fpm_pool_conf_path.
set_fact: ansible.builtin.set_fact:
php_fpm_pool_conf_path: "{{ __php_fpm_pool_conf_path }}" php_fpm_pool_conf_path: "{{ __php_fpm_pool_conf_path }}"
when: php_fpm_pool_conf_path is not defined when: php_fpm_pool_conf_path is not defined
- name: Define php_fpm_pool_user. - name: Define php_fpm_pool_user.
set_fact: ansible.builtin.set_fact:
php_fpm_pool_user: "{{ __php_fpm_pool_user }}" php_fpm_pool_user: "{{ __php_fpm_pool_user }}"
when: php_fpm_pool_user is not defined when: php_fpm_pool_user is not defined
- name: Define php_fpm_pool_group. - name: Define php_fpm_pool_group.
set_fact: ansible.builtin.set_fact:
php_fpm_pool_group: "{{ __php_fpm_pool_group }}" php_fpm_pool_group: "{{ __php_fpm_pool_group }}"
when: php_fpm_pool_group is not defined when: php_fpm_pool_group is not defined
- name: Stat php_fpm_pool_conf_path - name: Stat php_fpm_pool_conf_path
stat: ansible.builtin.stat:
path: "{{ php_fpm_pool_conf_path | dirname }}" path: "{{ php_fpm_pool_conf_path | dirname }}"
register: php_fpm_pool_conf_path_dir_stat register: php_fpm_pool_conf_path_dir_stat
- name: Ensure the default pool directory exists. - name: Ensure the default pool directory exists.
file: ansible.builtin.file:
path: "{{ php_fpm_pool_conf_path | dirname }}" path: "{{ php_fpm_pool_conf_path | dirname }}"
state: directory state: directory
owner: root owner: root
group: root group: root
mode: 0755 mode: '0755'
when: php_fpm_pool_conf_path_dir_stat.stat.islnk is not defined when: php_fpm_pool_conf_path_dir_stat.stat.islnk is not defined
- name: Create fpm pools. - name: Create fpm pools.
template: ansible.builtin.template:
src: "{{ item.pool_template | default('www.conf.j2', true) }}" src: "{{ item.pool_template | default('www.conf.j2', true) }}"
dest: "{{ php_fpm_pool_conf_path | dirname }}/{{ item.pool_name }}.conf" dest: "{{ php_fpm_pool_conf_path | dirname }}/{{ item.pool_name }}.conf"
owner: root owner: root
group: root group: root
mode: 0644 mode: '0644'
force: true force: true
loop: "{{ php_fpm_pools | default([], true) }}" loop: "{{ php_fpm_pools | default([], true) }}"
when: php_enable_php_fpm when: php_enable_php_fpm
notify: restart php-fpm notify: Restart php-fpm
- name: Ensure php-fpm is started and enabled at boot (if configured). - name: Ensure php-fpm is started and enabled at boot (if configured).
service: ansible.builtin.service:
name: "{{ php_fpm_daemon }}" name: "{{ php_fpm_daemon }}"
state: "{{ php_fpm_state }}" state: "{{ php_fpm_state }}"
enabled: "{{ php_fpm_enabled_on_boot }}" enabled: "{{ php_fpm_enabled_on_boot }}"

View file

@ -1,37 +1,37 @@
--- ---
- name: Check for existing OpCache config files. - name: Check for existing OpCache config files.
find: ansible.builtin.find:
paths: "{{ item }}" paths: "{{ item }}"
contains: 'zend_extension(\s+)?=(\s+)?opcache\.so' contains: 'zend_extension(\s+)?=(\s+)?opcache\.so'
register: php_installed_opcache_confs register: php_installed_opcache_confs
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
- name: Remove any non-role-supplied OpCache config files. - name: Remove any non-role-supplied OpCache config files.
file: ansible.builtin.file:
path: "{{ item.1.path }}" path: "{{ item.1.path }}"
state: absent state: absent
when: php_opcache_conf_filename != (item.1.path.split('/') | last) when: php_opcache_conf_filename != (item.1.path.split('/') | last)
with_subelements: with_subelements:
- "{{ php_installed_opcache_confs.results }}" - "{{ php_installed_opcache_confs.results }}"
- files - files
notify: restart webserver notify: Restart webserver
- name: Ensure OpCache config file is present. - name: Ensure OpCache config file is present.
template: ansible.builtin.template:
src: opcache.ini.j2 src: opcache.ini.j2
dest: "{{ item }}/{{ php_opcache_conf_filename }}" dest: "{{ item }}/{{ php_opcache_conf_filename }}"
owner: root owner: root
group: root group: root
force: true force: true
mode: 0644 mode: '0644'
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
when: php_opcache_enable | bool when: php_opcache_enable | bool
notify: restart webserver notify: Restart webserver
- name: Remove OpCache config file if OpCache is disabled. - name: Remove OpCache config file if OpCache is disabled.
file: ansible.builtin.file:
path: "{{ item }}/{{ php_opcache_conf_filename }}" path: "{{ item }}/{{ php_opcache_conf_filename }}"
state: absent state: absent
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
when: not php_opcache_enable | bool when: not php_opcache_enable | bool
notify: restart webserver notify: Restart webserver

View file

@ -4,7 +4,7 @@
path: "{{ item }}" path: "{{ item }}"
state: directory state: directory
follow: true follow: true
mode: 0755 mode: '0755'
with_items: with_items:
- "{{ php_conf_paths | flatten }}" - "{{ php_conf_paths | flatten }}"
- "{{ php_extension_conf_paths | flatten }}" - "{{ php_extension_conf_paths | flatten }}"
@ -15,7 +15,7 @@
dest: "{{ item }}/php.ini" dest: "{{ item }}/php.ini"
owner: root owner: root
group: root group: root
mode: 0644 mode: '0644'
with_items: "{{ php_conf_paths }}" with_items: "{{ php_conf_paths }}"
notify: restart webserver notify: Restart webserver
when: php_use_managed_ini when: php_use_managed_ini

View file

@ -1,6 +1,6 @@
--- ---
- name: Ensure dependencies for building from source are installed (RedHat). - name: Ensure dependencies for building from source are installed (RedHat).
package: ansible.builtin.package:
name: name:
- autoconf - autoconf
- automake - automake
@ -30,11 +30,13 @@
when: ansible_facts.os_family == 'RedHat' when: ansible_facts.os_family == 'RedHat'
- name: Update apt cache (Debian). - name: Update apt cache (Debian).
apt: update_cache=yes cache_valid_time=86400 ansible.builtin.apt:
update_cache: true
cache_valid_time: 86400
when: ansible_facts.os_family == 'Debian' when: ansible_facts.os_family == 'Debian'
- name: Ensure dependencies for building from source are installed (Debian). - name: Ensure dependencies for building from source are installed (Debian).
apt: ansible.builtin.apt:
name: name:
- build-essential - build-essential
- autoconf - autoconf
@ -62,29 +64,30 @@
when: ansible_facts.os_family == 'Debian' when: ansible_facts.os_family == 'Debian'
- name: Define php_fpm_daemon (if not defined already). - name: Define php_fpm_daemon (if not defined already).
set_fact: ansible.builtin.set_fact:
php_fpm_daemon: "php-fpm" php_fpm_daemon: "php-fpm"
when: php_fpm_daemon is not defined when: php_fpm_daemon is not defined
- name: Check if gmp.h is already in a location accessible to gcc. - name: Check if gmp.h is already in a location accessible to gcc.
stat: path=/usr/include/gmp.h ansible.builtin.stat:
path: /usr/include/gmp.h
register: gmp_file register: gmp_file
- name: Ensure gmp.h is symlinked into a location accessible to gcc. - name: Ensure gmp.h is symlinked into a location accessible to gcc.
file: # noqa 208 ansible.builtin.file: # noqa: risky-file-permissions
src: "{{ php_source_install_gmp_path }}" src: "{{ php_source_install_gmp_path }}"
dest: /usr/include/gmp.h dest: /usr/include/gmp.h
state: link state: link
when: not gmp_file.stat.exists when: not gmp_file.stat.exists
- name: Check if PHP is installed. - name: Check if PHP is installed.
command: which php ansible.builtin.command: which php
changed_when: false changed_when: false
failed_when: false failed_when: false
register: php_installed register: php_installed
- name: Clone the PHP repository. - name: Clone the PHP repository.
git: ansible.builtin.git:
repo: "{{ php_source_repo }}" repo: "{{ php_source_repo }}"
dest: "{{ php_source_clone_dir }}" dest: "{{ php_source_clone_dir }}"
version: "{{ php_source_version }}" version: "{{ php_source_version }}"
@ -93,66 +96,69 @@
when: php_installed.rc != 0 when: php_installed.rc != 0
- name: Ensure PHP installation path exists. - name: Ensure PHP installation path exists.
file: ansible.builtin.file:
path: "{{ php_source_install_path }}" path: "{{ php_source_install_path }}"
state: directory state: directory
mode: 0755 mode: '0755'
when: php_installed.rc != 0 when: php_installed.rc != 0
- name: Build configure script. - name: Build configure script.
command: > ansible.builtin.command: ./buildconf --force
./buildconf --force args:
chdir={{ php_source_clone_dir }} chdir: "{{ php_source_clone_dir }}"
changed_when: php_installed.rc != 0
when: php_installed.rc != 0 when: php_installed.rc != 0
- name: Run configure script. - name: Run configure script.
command: > ansible.builtin.command: "{{ php_source_configure_command }}"
{{ php_source_configure_command }} args:
chdir={{ php_source_clone_dir }} chdir: "{{ php_source_clone_dir }}"
changed_when: php_installed.rc != 0
when: php_installed.rc != 0 when: php_installed.rc != 0
- name: Make and install PHP. - name: Make and install PHP.
command: > ansible.builtin.command: "{{ item }}"
{{ item }} args:
chdir={{ php_source_clone_dir }} chdir: "{{ php_source_clone_dir }}"
with_items: with_items:
- "{{ php_source_make_command }}" - "{{ php_source_make_command }}"
- make install - make install
changed_when: php_installed.rc != 0
when: php_installed.rc != 0 when: php_installed.rc != 0
- name: Ensure php executable is symlinked into a standard path. - name: Ensure php executable is symlinked into a standard path.
file: # noqa 208 ansible.builtin.file: # noqa: risky-file-permissions
src: "{{ php_source_install_path }}/bin/php" src: "{{ php_source_install_path }}/bin/php"
dest: /usr/bin/php dest: /usr/bin/php
state: link state: link
# PHP FPM configuration. # PHP FPM configuration.
- name: Ensure php-fpm executable is symlinked into a standard path. - name: Ensure php-fpm executable is symlinked into a standard path.
file: # noqa 208 ansible.builtin.file: # noqa: risky-file-permissions
src: "{{ php_source_install_path }}/sbin/php-fpm" src: "{{ php_source_install_path }}/sbin/php-fpm"
dest: "/usr/sbin/{{ php_fpm_daemon }}" dest: "/usr/sbin/{{ php_fpm_daemon }}"
state: link state: link
when: "'--enable-fpm' in php_source_configure_command" when: "'--enable-fpm' in php_source_configure_command"
- name: Ensure php-fpm init script is installed. - name: Ensure php-fpm init script is installed.
template: ansible.builtin.template:
src: fpm-init.j2 src: fpm-init.j2
dest: "/etc/init.d/{{ php_fpm_daemon }}" dest: "/etc/init.d/{{ php_fpm_daemon }}"
mode: 0755 mode: '0755'
when: "'--enable-fpm' in php_source_configure_command" when: "'--enable-fpm' in php_source_configure_command"
notify: restart php-fpm notify: Restart php-fpm
- name: Ensure php-fpm config directory exists. - name: Ensure php-fpm config directory exists.
file: ansible.builtin.file:
path: "{{ php_fpm_conf_path }}" path: "{{ php_fpm_conf_path }}"
state: directory state: directory
mode: 0755 mode: '0755'
when: "'--enable-fpm' in php_source_configure_command" when: "'--enable-fpm' in php_source_configure_command"
- name: Ensure php-fpm config file is installed. - name: Ensure php-fpm config file is installed.
template: ansible.builtin.template:
src: php-fpm.conf.j2 src: php-fpm.conf.j2
dest: "{{ php_fpm_conf_path }}/php-fpm.conf" dest: "{{ php_fpm_conf_path }}/php-fpm.conf"
mode: 0644 mode: '0644'
when: "'--enable-fpm' in php_source_configure_command" when: "'--enable-fpm' in php_source_configure_command"
notify: restart php-fpm notify: Restart php-fpm

View file

@ -1,87 +1,94 @@
--- ---
# Variable setup. # Variable setup.
- name: Include OS-specific variables. - name: Include OS-specific variables.
include_vars: "{{ ansible_facts.os_family }}.yml" ansible.builtin.include_vars: "{{ ansible_facts.os_family }}.yml"
- name: Include distribution and version-specific vars. - name: Include distribution and version-specific vars.
include_vars: "{{ item }}" ansible.builtin.include_vars: "{{ item }}"
with_first_found: with_first_found:
- files: - files:
- "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml" - "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
skip: true skip: true
- name: Set the default PHP version for Debian-based OSes. - name: Set the default PHP version for Debian-based OSes.
set_fact: ansible.builtin.set_fact:
php_default_version_debian: "{{ __php_default_version_debian }}" php_default_version_debian: "{{ __php_default_version_debian }}"
when: php_default_version_debian is not defined and ansible_facts.os_family == 'Debian' when: php_default_version_debian is not defined and ansible_facts.os_family == 'Debian'
- name: Define the name of the JSON extension package on Debian for PHP <8. - name: Define the name of the JSON extension package on Debian for PHP <8.
set_fact: ansible.builtin.set_fact:
__php_json_package_debian: "{{ 'php' + php_default_version_debian + '-json' }}" __php_json_package_debian: "{{ 'php' + php_default_version_debian + '-json' }}"
when: ansible_facts.os_family == 'Debian' and php_default_version_debian is version('8.0', '<') when: ansible_facts.os_family == 'Debian' and php_default_version_debian is version('8.0', '<')
- name: Add the JSON extension on Debian for PHP <8. - name: Add the JSON extension on Debian for PHP <8.
set_fact: ansible.builtin.set_fact:
__php_packages: "{{ __php_packages + [__php_json_package_debian] }}" __php_packages: "{{ __php_packages + [__php_json_package_debian] }}"
when: __php_json_package_debian is defined and __php_json_package_debian not in __php_packages when: __php_json_package_debian is defined and __php_json_package_debian not in __php_packages
- name: Define php_packages. - name: Define php_packages.
set_fact: ansible.builtin.set_fact:
php_packages: "{{ __php_packages | list }}" php_packages: "{{ __php_packages | list }}"
when: php_packages is not defined when: php_packages is not defined
- name: Define php_webserver_daemon. - name: Define php_webserver_daemon.
set_fact: ansible.builtin.set_fact:
php_webserver_daemon: "{{ __php_webserver_daemon }}" php_webserver_daemon: "{{ __php_webserver_daemon }}"
when: php_webserver_daemon is not defined when: php_webserver_daemon is not defined
- name: Define php_conf_paths. - name: Define php_conf_paths.
set_fact: ansible.builtin.set_fact:
php_conf_paths: "{{ __php_conf_paths }}" php_conf_paths: "{{ __php_conf_paths }}"
when: php_conf_paths is not defined when: php_conf_paths is not defined
- name: Define php_extension_conf_paths. - name: Define php_extension_conf_paths.
set_fact: ansible.builtin.set_fact:
php_extension_conf_paths: "{{ __php_extension_conf_paths }}" php_extension_conf_paths: "{{ __php_extension_conf_paths }}"
when: php_extension_conf_paths is not defined when: php_extension_conf_paths is not defined
- name: Define php_apc_conf_filename. - name: Define php_apc_conf_filename.
set_fact: ansible.builtin.set_fact:
php_apc_conf_filename: "{{ __php_apc_conf_filename }}" php_apc_conf_filename: "{{ __php_apc_conf_filename }}"
when: php_apc_conf_filename is not defined when: php_apc_conf_filename is not defined
- name: Define php_opcache_conf_filename (Ubuntu 16.04). - name: Define php_opcache_conf_filename (Ubuntu 16.04).
set_fact: ansible.builtin.set_fact:
php_opcache_conf_filename: "10-opcache.ini" php_opcache_conf_filename: "10-opcache.ini"
when: php_opcache_conf_filename is not defined and ansible_facts.distribution_version == "16.04" when: php_opcache_conf_filename is not defined and ansible_facts.distribution_version == "16.04"
- name: Define php_opcache_conf_filename. - name: Define php_opcache_conf_filename.
set_fact: ansible.builtin.set_fact:
php_opcache_conf_filename: "{{ __php_opcache_conf_filename }}" php_opcache_conf_filename: "{{ __php_opcache_conf_filename }}"
when: php_opcache_conf_filename is not defined when: php_opcache_conf_filename is not defined
- name: Define php_fpm_conf_path. - name: Define php_fpm_conf_path.
set_fact: ansible.builtin.set_fact:
php_fpm_conf_path: "{{ __php_fpm_conf_path }}" php_fpm_conf_path: "{{ __php_fpm_conf_path }}"
when: php_fpm_conf_path is not defined when: php_fpm_conf_path is not defined
# Setup/install tasks. # Setup/install tasks.
- include_tasks: setup-RedHat.yml - name: Setup RedHat
ansible.builtin.include_tasks: setup-RedHat.yml
when: when:
- not php_install_from_source - not php_install_from_source
- ansible_facts.os_family == 'RedHat' - ansible_facts.os_family == 'RedHat'
- include_tasks: setup-Debian.yml - name: Setup Debian
ansible.builtin.include_tasks: setup-Debian.yml
when: when:
- not php_install_from_source - not php_install_from_source
- ansible_facts.os_family == 'Debian' - ansible_facts.os_family == 'Debian'
# Install PHP from source when php_install_from_source is true. # Install PHP from source when php_install_from_source is true.
- include_tasks: install-from-source.yml - name: Install from source
ansible.builtin.include_tasks: install-from-source.yml
when: php_install_from_source when: php_install_from_source
# Configure PHP. # Configure PHP.
- include_tasks: configure.yml - name: Configure PHP
- include_tasks: configure-apcu.yml ansible.builtin.include_tasks: configure.yml
- include_tasks: configure-opcache.yml - name: Configure APCu
- include_tasks: configure-fpm.yml ansible.builtin.include_tasks: configure-apcu.yml
- name: Configure OpCache
ansible.builtin.include_tasks: configure-opcache.yml
- name: Configure FPM
ansible.builtin.include_tasks: configure-fpm.yml

View file

@ -1,27 +1,29 @@
--- ---
- name: Update apt cache. - name: Update apt cache.
apt: update_cache=yes cache_valid_time=86400 ansible.builtin.apt:
update_cache: true
cache_valid_time: 86400
- name: Ensure PHP packages are installed. - name: Ensure PHP packages are installed.
apt: ansible.builtin.apt:
name: "{{ php_packages + php_packages_extra }}" name: "{{ php_packages + php_packages_extra }}"
state: "{{ php_packages_state }}" state: "{{ php_packages_state }}"
install_recommends: "{{ php_install_recommends }}" install_recommends: "{{ php_install_recommends }}"
register: php_package_install register: php_package_install
notify: restart webserver notify: Restart webserver
- name: Delete APCu configuration file if this role will provide one. - name: Delete APCu configuration file if this role will provide one.
file: ansible.builtin.file:
path: "{{ item }}/{{ php_apc_conf_filename }}" path: "{{ item }}/{{ php_apc_conf_filename }}"
state: absent state: absent
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
when: php_enable_apc and php_package_install.changed when: php_enable_apc and php_package_install.changed
notify: restart webserver notify: Restart webserver
- name: Delete OpCache configuration file if this role will provide one. - name: Delete OpCache configuration file if this role will provide one.
file: ansible.builtin.file:
path: "{{ item }}/{{ php_opcache_conf_filename }}" path: "{{ item }}/{{ php_opcache_conf_filename }}"
state: absent state: absent
with_items: "{{ php_extension_conf_paths }}" with_items: "{{ php_extension_conf_paths }}"
when: php_opcache_enable | bool and php_package_install.changed when: php_opcache_enable | bool and php_package_install.changed
notify: restart webserver notify: Restart webserver

View file

@ -3,10 +3,10 @@
ansible.builtin.dnf: ansible.builtin.dnf:
name: "https://rpms.remirepo.net/enterprise/remi-release-{{ ansible_distribution_major_version }}.rpm" name: "https://rpms.remirepo.net/enterprise/remi-release-{{ ansible_distribution_major_version }}.rpm"
state: present state: present
disable_gpg_check: yes disable_gpg_check: true
- name: Ensure PHP packages are installed. - name: Ensure PHP packages are installed.
package: ansible.builtin.package:
name: "{{ php_packages + php_packages_extra }}" name: "{{ php_packages + php_packages_extra }}"
state: "{{ php_packages_state }}" state: "{{ php_packages_state }}"
enablerepo: "{{ php_enablerepo | default(omit, true) }}" enablerepo: "{{ php_enablerepo | default(omit, true) }}"
notify: restart webserver notify: Restart webserver

View file

@ -0,0 +1,7 @@
---
skip_list:
# - 'yaml'
- no-handler
- role-name
write_list:
- fqcn

5
roles/postgresql/.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
*.retry
*/__pycache__
*.pyc
.cache

View file

@ -0,0 +1,10 @@
---
extends: default
rules:
line-length:
max: 120
level: warning
ignore: |
.github/workflows/stale.yml

195
roles/postgresql/README.md Normal file
View file

@ -0,0 +1,195 @@
# Ansible Role: PostgreSQL
[![CI](https://github.com/geerlingguy/ansible-role-postgresql/actions/workflows/ci.yml/badge.svg)](https://github.com/geerlingguy/ansible-role-postgresql/actions/workflows/ci.yml)
Installs and configures PostgreSQL server on RHEL/CentOS or Debian/Ubuntu servers.
## Requirements
No special requirements; note that this role requires root access, so either run it in a playbook with a global `become: yes`, or invoke the role in your playbook like:
```yaml
- hosts: database
roles:
- role: postgresql
become: yes
```
## Role Variables
Available variables are listed below, along with default values (see `defaults/main.yml`):
```yaml
postgresql_enablerepo: ""
```
(RHEL/CentOS only) You can set a repo to use for the PostgreSQL installation by passing it in here.
```yaml
postgresql_restarted_state: "restarted"
```
Set the state of the service when configuration changes are made. Recommended values are `restarted` or `reloaded`.
```yaml
postgresql_python_library: python-psycopg2
```
Library used by Ansible to communicate with PostgreSQL. If you are using Python 3 (e.g. set via `ansible_python_interpreter`), you should change this to `python3-psycopg2`.
```yaml
postgresql_user: postgres
postgresql_group: postgres
```
The user and group under which PostgreSQL will run.
```yaml
postgresql_unix_socket_directories:
- /var/run/postgresql
```
The directories (usually one, but can be multiple) where PostgreSQL's socket will be created.
```yaml
postgresql_service_state: started
postgresql_service_enabled: true
```
Control the state of the postgresql service and whether it should start at boot time.
```yaml
postgresql_global_config_options:
- option: unix_socket_directories
value: '{{ postgresql_unix_socket_directories | join(",") }}'
- option: log_directory
value: 'log'
```
Global configuration options that will be set in `postgresql.conf`.
For PostgreSQL versions older than 9.3 you need to at least override this variable and set the `option` to `unix_socket_directory`.
If you override the value of `option: log_directory` with another path, relative or absolute, then this role will create it for you.
```yaml
postgresql_hba_entries:
- { type: local, database: all, user: postgres, auth_method: peer }
- { type: local, database: all, user: all, auth_method: peer }
- { type: host, database: all, user: all, address: '127.0.0.1/32', auth_method: md5 }
- { type: host, database: all, user: all, address: '::1/128', auth_method: md5 }
```
Configure [host based authentication](https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html) entries to be set in the `pg_hba.conf`. Options for entries include:
- `type` (required)
- `database` (required)
- `user` (required)
- `address` (one of this or the following two are required)
- `ip_address`
- `ip_mask`
- `auth_method` (required)
- `auth_options` (optional)
If overriding, make sure you copy all of the existing entries from `defaults/main.yml` if you need to preserve existing entries.
```yaml
postgresql_locales:
- 'en_US.UTF-8'
```
(Debian/Ubuntu only) Used to generate the locales used by PostgreSQL databases.
```yaml
postgresql_databases:
- name: exampledb # required; the rest are optional
lc_collate: # defaults to 'en_US.UTF-8'
lc_ctype: # defaults to 'en_US.UTF-8'
encoding: # defaults to 'UTF-8'
template: # defaults to 'template0'
login_host: # defaults to 'localhost'
login_password: # defaults to not set
login_user: # defaults to 'postgresql_user'
login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
port: # defaults to not set
owner: # defaults to postgresql_user
state: # defaults to 'present'
```
A list of databases to ensure exist on the server. Only the `name` is required; all other properties are optional.
```yaml
postgresql_users:
- name: jdoe #required; the rest are optional
password: # defaults to not set
encrypted: # defaults to not set
role_attr_flags: # defaults to not set
db: # defaults to not set
login_host: # defaults to 'localhost'
login_password: # defaults to not set
login_user: # defaults to '{{ postgresql_user }}'
login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
port: # defaults to not set
state: # defaults to 'present'
```
A list of users to ensure exist on the server. Only the `name` is required; all other properties are optional.
```yaml
postgresql_privs:
- db: exampledb # database (required)
roles: jdoe # role(s) the privs apply to (required)
privs: # comma separated list of privileges - defaults to not set
type: # type of database object to set privileges on - defaults to not set
objs: # list of database objects to set privileges on - defaults to not set
schema: # defaults to not set
session_role: # defaults to not set
fail_on_role: # defaults to true
grant_option: # defaults to not set
target_roles: # defaults to not set
login_host: # defaults to 'localhost'
login_password: # defaults to not set
login_user: # defaults to '{{ postgresql_user }}'
login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
port: # defaults to not set
state: # defaults to 'present'
```
A list of privileges to configure (new in role version 4.0.0).
```yaml
postgres_users_no_log: true
```
Whether to output user data (which may contain sensitive information, like passwords) when managing users.
```yaml
postgresql_version: [OS-specific]
postgresql_data_dir: [OS-specific]
postgresql_bin_path: [OS-specific]
postgresql_config_path: [OS-specific]
postgresql_daemon: [OS-specific]
postgresql_packages: [OS-specific]
```
OS-specific variables that are set by include files in this role's `vars` directory. These shouldn't be overridden unless you're using a version of PostgreSQL that wasn't installed using system packages.
## Dependencies
None.
## Example Playbook
```yaml
- hosts: database
become: yes
vars_files:
- vars/main.yml
roles:
- geerlingguy.postgresql
```
*Inside `vars/main.yml`*:
```yaml
postgresql_databases:
- name: example_db
postgresql_users:
- name: example_user
password: supersecure
```

View file

@ -0,0 +1,163 @@
---
# RHEL/CentOS only. Set a repository to use for PostgreSQL installation.
postgresql_enablerepo: ""
# Set postgresql state when configuration changes are made. Recommended values:
# `restarted` or `reloaded`
postgresql_restarted_state: restarted
postgresql_python_library: python-psycopg2
postgresql_user: postgres
postgresql_group: postgres
# `md5` or `scram-sha-256` (https://www.postgresql.org/docs/10/auth-methods.html)
postgresql_auth_method: "{{ ansible_fips | ternary('scram-sha-256', 'md5') }}"
postgresql_unix_socket_directories:
- /var/run/postgresql
postgresql_service_state: started
postgresql_service_enabled: true
# Global configuration options that will be set in postgresql.conf.
postgresql_global_config_options:
- option: unix_socket_directories
value: '{{ postgresql_unix_socket_directories | join(",") }}'
- option: log_directory
value: log
# Enabe timesaledb
timescaledb_enabled: false
# Host based authentication (hba) entries to be added to the pg_hba.conf. This
# variable's defaults reflect the defaults that come with a fresh installation.
postgresql_hba_entries:
- type: local
database: all
user: postgres
auth_method: peer
- type: local
database: all
user: all
auth_method: peer
- type: host
database: all
user: all
address: 127.0.0.1/32
auth_method: "{{ postgresql_auth_method }}"
- type: host
database: all
user: all
address: ::1/128
auth_method: "{{ postgresql_auth_method }}"
# Debian only. Used to generate the locales used by PostgreSQL databases.
postgresql_locales:
- en_US.UTF-8
# Databases to ensure exist.
postgresql_databases: []
# - name: exampledb # required; the rest are optional
# lc_collate: # defaults to 'en_US.UTF-8'
# lc_ctype: # defaults to 'en_US.UTF-8'
# encoding: # defaults to 'UTF-8'
# template: # defaults to 'template0'
# login_host: # defaults to 'localhost'
# login_password: # defaults to not set
# login_user: # defaults to '{{ postgresql_user }}'
# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
# port: # defaults to not set
# owner: # defaults to postgresql_user
# state: # defaults to 'present'
# Users to ensure exist.
postgresql_users: []
# - name: jdoe #required; the rest are optional
# password: # defaults to not set
# encrypted: # defaults to not set
# role_attr_flags: # defaults to not set
# db: # defaults to not set
# login_host: # defaults to 'localhost'
# login_password: # defaults to not set
# login_user: # defaults to '{{ postgresql_user }}'
# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
# port: # defaults to not set
# state: # defaults to 'present'
# Privileges to configure
# see
# https://docs.ansible.com/ansible/latest/collections/community/postgresql/postgresql_privs_module.html#ansible-collections-community-postgresql-postgresql-privs-module
postgresql_privs: []
# - db: exampledb # database (required)
# roles: jdoe # role(s) the privs apply to (required)
# privs: # comma separated list of privileges - defaults to not set
# type: # type of database object to set privileges on - defaults to not set
# objs: # list of database objects to set privileges on - defaults to not set
# schema: # defaults to not set
# session_role: # defaults to not set
# fail_on_role: # defaults to true
# grant_option: # defaults to not set
# target_roles: # defaults to not set
# login_host: # defaults to 'localhost'
# login_password: # defaults to not set
# login_user: # defaults to '{{ postgresql_user }}'
# login_unix_socket: # defaults to 1st of postgresql_unix_socket_directories
# port: # defaults to not set
# state: # defaults to 'present'
# Whether to output user data when managing users.
postgres_users_no_log: true
# Useful hints:
# To start replication
# Create replication user on master
# Dont forget to add rep_user to pg_hba.conf
# TYPE DATABASE USER ADDRESS METHOD
# host all rep_user 10.203.0.0/16 scram-sha-256
# On PostgreSQL:
# CREATE ROLE rep_user WITH REPLICATION LOGIN PASSWORD 'superstrongpass123';
# GRANT CONNECT ON DATABASE <db_name> TO rep_user;
# GRANT USAGE ON SCHEMA public TO rep_user;
# GRANT SELECT ON ALL TABLES IN SCHEMA public TO rep_user;
# DO $$
# DECLARE
# tables_list text;
# BEGIN
# SELECT string_agg(quote_ident(schemaname) || '.' || quote_ident(tablename), ', ')
# INTO tables_list
# FROM pg_tables
# WHERE schemaname = 'public'
# AND tablename NOT IN ('null' ); -- Список исключаемых таблиц
# IF tables_list IS NOT NULL THEN
# EXECUTE 'CREATE PUBLICATION export_tables FOR TABLE ' || tables_list;
# ELSE
# RAISE NOTICE 'Нет таблиц для добавления в публикацию';
# END IF;
# END $$;
# Migrate db schema to file
# sudo -u postgres pg_dump -s -d zabbix > schema_dump.sql
# Upload schema_dump.sql to secondary server
# CREATE DATABASE db_name;
# Put schema_dump.sql on it
# cat schema_dump.sql | sudo -u postgres psql db_name
# Create subscription on secondary server
# CREATE SUBSCRIPTION my_import CONNECTION 'host=[hostname] user=rep_user dbname=[db] password=superstrongpass123' PUBLICATION export_tables;
#
# -- Check pgsql replication status
# SELECT
# srrelid::regclass AS table_name,
# srsubstate AS state_code,
# CASE srsubstate
# WHEN 'i' THEN 'initialize'
# WHEN 'd' THEN 'data copy'
# WHEN 'f' THEN 'finished copy'
# WHEN 's' THEN 'synchronized'
# WHEN 'r' THEN 'ready (streaming)'
# END AS state_description,
# srsublsn AS lsn
# FROM pg_subscription_rel;

View file

@ -0,0 +1,6 @@
---
- name: restart postgresql
ansible.builtin.service:
name: "{{ postgresql_daemon }}"
state: "{{ postgresql_restarted_state }}"
sleep: 5

View file

@ -0,0 +1,29 @@
---
- name: Configure global settings.
ansible.builtin.lineinfile:
dest: "{{ postgresql_config_path }}/postgresql.conf"
regexp: ^#?{{ item.option }}.+$
line: "{{ item.option }} = '{{ item.value }}'"
state: "{{ item.state | default('present') }}"
mode: "0644"
with_items: "{{ postgresql_global_config_options }}"
notify: restart postgresql
- name: Configure host based authentication (if entries are configured).
ansible.builtin.template:
src: pg_hba.conf.j2
dest: "{{ postgresql_config_path }}/pg_hba.conf"
owner: "{{ postgresql_user }}"
group: "{{ postgresql_group }}"
mode: "0600"
notify: restart postgresql
when: postgresql_hba_entries | length > 0
- name: Ensure PostgreSQL unix socket dirs exist.
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: "{{ postgresql_user }}"
group: "{{ postgresql_group }}"
mode: "{{ postgresql_unix_socket_directories_mode }}"
with_items: "{{ postgresql_unix_socket_directories }}"

View file

@ -0,0 +1,21 @@
---
- name: Ensure PostgreSQL databases are present.
community.postgresql.postgresql_db:
name: "{{ item.name }}"
lc_collate: "{{ item.lc_collate | default('en_US.UTF-8') }}"
lc_ctype: "{{ item.lc_ctype | default('en_US.UTF-8') }}"
encoding: "{{ item.encoding | default('UTF-8') }}"
template: "{{ item.template | default('template0') }}"
login_host: "{{ item.login_host | default('localhost') }}"
login_password: "{{ item.login_password | default(omit) }}"
login_user: "{{ item.login_user | default(postgresql_user) }}"
login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}"
port: "{{ item.port | default(omit) }}"
owner: "{{ item.owner | default(postgresql_user) }}"
state: "{{ item.state | default('present') }}"
with_items: "{{ postgresql_databases }}"
become: true
become_user: "{{ postgresql_user }}"
# See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509
vars:
ansible_ssh_pipelining: true

View file

@ -0,0 +1,37 @@
---
- name: Set PostgreSQL environment variables.
ansible.builtin.template:
src: postgres.sh.j2
dest: /etc/profile.d/postgres.sh
mode: "0644"
notify: restart postgresql
- name: Ensure PostgreSQL data directory exists.
ansible.builtin.file:
path: "{{ postgresql_data_dir }}"
owner: "{{ postgresql_user }}"
group: "{{ postgresql_group }}"
state: directory
mode: "0700"
- name: Check if PostgreSQL database is initialized.
ansible.builtin.stat:
path: "{{ postgresql_data_dir }}/PG_VERSION"
register: pgdata_dir_version
- name: Ensure PostgreSQL database is initialized.
ansible.builtin.command: "{{ postgresql_bin_path }}/initdb -D {{ postgresql_data_dir }}"
when: not pgdata_dir_version.stat.exists
become: true
become_user: "{{ postgresql_user }}"
# See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509
vars:
ansible_ssh_pipelining: true
- name: Ensure PostgreSQL log directory exists.
ansible.builtin.file:
path: "{{ postgresql_effective_log_dir }}"
owner: "{{ postgresql_user }}"
group: "{{ postgresql_group }}"
state: directory
mode: "0700"

View file

@ -0,0 +1,38 @@
---
# Variable configuration.
- name: Include Variables
ansible.builtin.include_tasks: variables.yml
- name: ArchLinux-setup
ansible.builtin.include_tasks: setup-Archlinux.yml
when: ansible_facts.os_family == 'Archlinux'
- name: Debian-setup
ansible.builtin.include_tasks: setup-Debian.yml
when: ansible_facts.os_family == 'Debian'
- name: RHEL-Setup
ansible.builtin.include_tasks: setup-RedHat.yml
when: ansible_facts.os_family == 'RedHat'
- name: Enable TimeScaleDB
ansible.builtin.include_tasks: timescaledb.yml
when: timescaledb_enabled is true
- name: PostgreSQL Initialization
ansible.builtin.include_tasks: initialize.yml
- name: PostgreSQL Configuration
ansible.builtin.include_tasks: configure.yml
- name: Ensure PostgreSQL is started and enabled on boot.
ansible.builtin.service:
name: "{{ postgresql_daemon }}"
state: "{{ postgresql_service_state }}"
enabled: "{{ postgresql_service_enabled }}"
# Configure PostgreSQL.
- name: Create PostgreSQL users
ansible.builtin.import_tasks: users.yml
- name: Create PostgreSQL databases
ansible.builtin.import_tasks: databases.yml
- name: Set PostgreSQL user properties
ansible.builtin.import_tasks: users_props.yml

View file

@ -0,0 +1,23 @@
---
- name: Ensure PostgreSQL Python libraries are installed.
community.general.pacman:
name: "{{ postgresql_python_library }}"
state: present
- name: Ensure PostgreSQL packages are installed.
community.general.pacman:
name: "{{ postgresql_packages }}"
state: present
- name: Ensure all configured locales are present.
community.general.locale_gen:
name: "{{ item }}"
state: present
with_items: "{{ postgresql_locales }}"
register: locale_gen_result
- name: Force-restart PostgreSQL after new locales are generated.
ansible.builtin.systemd:
name: "{{ postgresql_daemon }}"
state: restarted
when: locale_gen_result.changed

View file

@ -0,0 +1,23 @@
---
- name: Ensure PostgreSQL Python libraries are installed.
ansible.builtin.apt:
name: "{{ postgresql_python_library }}"
state: present
- name: Ensure PostgreSQL packages are installed.
ansible.builtin.apt:
name: "{{ postgresql_packages }}"
state: present
- name: Ensure all configured locales are present.
community.general.locale_gen:
name: "{{ item }}"
state: present
with_items: "{{ postgresql_locales }}"
register: locale_gen_result
- name: Force-restart PostgreSQL after new locales are generated.
ansible.builtin.service:
name: "{{ postgresql_daemon }}"
state: restarted
when: locale_gen_result.changed

View file

@ -0,0 +1,47 @@
---
- name: Install postgres repo
ansible.builtin.dnf:
name: https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
state: present
- name: Ensure PostgreSQL packages are installed.
ansible.builtin.dnf:
name: "{{ postgresql_packages }}"
state: present
enablerepo: "{{ postgresql_enablerepo | default(omit, true) }}"
# Don't let postgresql-contrib cause the /usr/bin/python symlink
# to be installed, which breaks later Ansible runs on Fedora 30,
# and affects system behavior in multiple ways.
exclude: python-unversioned-command
- name: Ensure PostgreSQL Python libraries are installed.
ansible.builtin.dnf:
name: "{{ postgresql_python_library }}"
state: present
enablerepo: "{{ postgresql_enablerepo | default(omit, true) }}"
- name: Add TimescaleDB repository
ansible.builtin.yum_repository:
name: timescale_timescaledb
description: TimescaleDB Repository
baseurl: https://packagecloud.io/timescale/timescaledb/el/{{ ansible_distribution_major_version }}/$basearch
gpgcheck: true
gpgkey: https://packagecloud.io/timescale/timescaledb/gpgkey
enabled: true
- name: Install TimescaleDB
ansible.builtin.dnf:
name: timescaledb-2-postgresql-{{ postgresql_version }}
state: present
enablerepo: timescale_timescaledb
disable_gpg_check: true
when: timescaledb_enabled is true
- name: Add kernel parameter to sysctl.d
ansible.posix.sysctl:
name: kernel.io_uring_disabled # The parameter name
value: "0" # The desired value (use strings)
sysctl_file: /etc/sysctl.d/postgres.conf # Custom drop-in path
state: present # Ensure it is in the file
reload: true # Apply to running kernel now
sysctl_set: true # Verify value with 'sysctl -w'

View file

@ -0,0 +1,11 @@
---
- name: Add TimescaleDB to global config options list
ansible.builtin.set_fact:
postgresql_global_config_options: "{{ postgresql_global_config_options + [item] }}"
loop:
- option: shared_preload_libraries
value: timescaledb
- option: timescaledb.license
value: timescale
- option: timescaledb.max_background_workers
value: "{{ (ansible_processor_vcpus - 2) | int | default(4) }}"

View file

@ -0,0 +1,19 @@
---
- name: Ensure PostgreSQL users are present.
community.postgresql.postgresql_user:
name: "{{ item.name }}"
password: "{{ item.password | default(omit) }}"
login_host: "{{ item.login_host | default('localhost') }}"
login_password: "{{ item.login_password | default(omit) }}"
login_user: "{{ item.login_user | default(postgresql_user) }}"
login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}"
port: "{{ item.port | default(omit) }}"
with_items: "{{ postgresql_users }}"
no_log: "{{ postgres_users_no_log }}"
become: true
become_user: "{{ postgresql_user }}"
# See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509
vars:
ansible_ssh_pipelining: true
environment:
PGOPTIONS: "{{ (postgresql_auth_method == 'scram-sha-256') | ternary('-c password_encryption=scram-sha-256', '') }}"

View file

@ -0,0 +1,60 @@
---
- name: Ensure PostgreSQL users are configured correctly.
community.postgresql.postgresql_user:
name: "{{ item.name }}"
password: "{{ item.password | default(omit) }}"
encrypted: "{{ item.encrypted | default(omit) }}"
role_attr_flags: "{{ item.role_attr_flags | default(omit) }}"
db: "{{ item.db | default(omit) }}"
login_host: "{{ item.login_host | default('localhost') }}"
login_password: "{{ item.login_password | default(omit) }}"
login_user: "{{ item.login_user | default(postgresql_user) }}"
login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}"
port: "{{ item.port | default(omit) }}"
state: "{{ item.state | default('present') }}"
with_items: "{{ postgresql_users }}"
no_log: "{{ postgres_users_no_log }}"
become: true
become_user: "{{ postgresql_user }}"
# See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509
vars:
ansible_ssh_pipelining: true
environment:
PGOPTIONS: "{{ (postgresql_auth_method == 'scram-sha-256') | ternary('-c password_encryption=scram-sha-256', '') }}"
- name: Ensure PostgreSQL users do not use deprecated privileges settings
ansible.builtin.debug:
msg: Postgresql user {{ item.name }} uses deprecated privileges settings. See https://github.com/geerlingguy/ansible-role-postgresql/issues/254
with_items: "{{ postgresql_users }}"
no_log: "{{ postgres_users_no_log }}"
loop_control:
label: "{{ item.name }}"
when: item.priv is defined
- name: Ensure PostgreSQL users privileges are configured correctly.
community.postgresql.postgresql_privs:
roles: "{{ item.roles }}"
db: "{{ item.db }}"
privs: "{{ item.privs | default(omit) }}"
type: "{{ item.type | default(omit) }}"
objs: "{{ item.objs | default(omit) }}"
schema: "{{ item.schema | default(omit) }}"
session_role: "{{ item.session_role | default(omit) }}"
login_host: "{{ item.login_host | default('localhost') }}"
login_password: "{{ item.login_password | default(omit) }}"
login_user: "{{ item.login_user | default(postgresql_user) }}"
login_unix_socket: "{{ item.login_unix_socket | default(postgresql_unix_socket_directories[0]) }}"
port: "{{ item.port | default(omit) }}"
state: "{{ item.state | default('present') }}"
fail_on_role: "{{ item.fail_on_role | default(true) }}"
grant_option: "{{ item.grant_option | default(omit) }}"
target_roles: "{{ item.target_roles | default(omit) }}"
with_items: "{{ postgresql_privs }}"
no_log: "{{ postgres_users_no_log }}"
become: true
become_user: "{{ postgresql_user }}"
# See: https://github.com/ansible/ansible/issues/16048#issuecomment-229012509
vars:
ansible_ssh_pipelining: true
environment:
PGOPTIONS: "{{ (postgresql_auth_method == 'scram-sha-256') | ternary('-c password_encryption=scram-sha-256', '') }}"

View file

@ -0,0 +1,132 @@
---
# Variable configuration.
- name: Include OS-specific variables (Debian).
ansible.builtin.include_vars: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version.split('.')[0] }}.yml"
when: ansible_facts.os_family == 'Debian'
- name: Include OS-specific variables (RedHat).
ansible.builtin.include_vars: "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_version.split('.')[0] }}.yml"
when:
- ansible_facts.os_family == 'RedHat'
- ansible_facts.distribution != 'Fedora'
- ansible_facts.distribution != 'Amazon'
- name: Include OS-specific variables (Amazon).
ansible.builtin.include_vars: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
when: ansible_facts.distribution == 'Amazon'
- name: Include OS-specific variables (Fedora).
ansible.builtin.include_vars: "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_version.split('.')[0] }}.yml"
when: ansible_facts.distribution == 'Fedora'
- name: Define postgresql_packages.
ansible.builtin.set_fact:
postgresql_packages: "{{ __postgresql_packages | list }}"
when: postgresql_packages is not defined
- name: Define postgresql_version.
ansible.builtin.set_fact:
postgresql_version: "{{ __postgresql_version }}"
when: postgresql_version is not defined
- name: Define postgresql_daemon.
ansible.builtin.set_fact:
postgresql_daemon: "{{ __postgresql_daemon }}"
when: postgresql_daemon is not defined
- name: Define postgresql_data_dir.
ansible.builtin.set_fact:
postgresql_data_dir: "{{ __postgresql_data_dir }}"
when: postgresql_data_dir is not defined
- name: Define postgresql_bin_path.
ansible.builtin.set_fact:
postgresql_bin_path: "{{ __postgresql_bin_path }}"
when: postgresql_bin_path is not defined
- name: Define postgresql_config_path.
ansible.builtin.set_fact:
postgresql_config_path: "{{ __postgresql_config_path }}"
when: postgresql_config_path is not defined
- name: Define postgresql_unix_socket_directories_mode.
ansible.builtin.set_fact:
postgresql_unix_socket_directories_mode: >-
{{ __postgresql_unix_socket_directories_mode | default('02775') }}
when: postgresql_unix_socket_directories_mode is not defined
- name: Define postgresql_log_dir.
ansible.builtin.set_fact:
# postgresql_global_config_options is an array but its keys are unique, so it can be converted to dict,
# to easily get the value under the 'log_directory' key
postgresql_log_dir: "{{ (postgresql_global_config_options | items2dict(key_name='option', value_name='value')).log_directory }}"
- name: Define postgresql_effective_log_dir, if postgresql_log_dir is absolute
ansible.builtin.set_fact:
postgresql_effective_log_dir: "{{ postgresql_log_dir }}"
when: postgresql_log_dir is match("/")
- name: Define postgresql_effective_log_dir, if postgresql_log_dir is relative
ansible.builtin.set_fact:
postgresql_effective_log_dir: "{{ postgresql_data_dir }}/{{ postgresql_log_dir }}"
when: postgresql_log_dir is not match("/")
# Very useful https://pgtune.leopard.in.ua/
- name: Add PostgresSQL optimizations to global config options list
ansible.builtin.set_fact:
postgresql_global_config_options: "{{ postgresql_global_config_options + [item] }}"
loop:
- option: listen_addresses
value: "{{ posgtgresql_ipv4 | default(ansible_default_ipv4.address) }}"
- option: port
value: "{{ postgresql_ipv4_port | default('5432') }}"
- option: max_connections
value: "{{ (ansible_processor_vcpus * 100) | int }}"
- option: max_worker_processes
value: "{{ ansible_processor_vcpus * 2 | default(4) }}"
- option: max_parallel_workers_per_gather
value: "{{ (ansible_processor_vcpus / 2) | int | default(2) }}"
- option: max_parallel_workers
value: "{{ ansible_processor_vcpus | default(4) }}"
- option: max_parallel_maintenance_workers
value: 2
- option: shared_buffers
value: "{{ (ansible_memtotal_mb / 4) | int }}MB"
- option: effective_cache_size
value: "{{ (ansible_memtotal_mb * 3 / 4) | int }}MB"
- option: maintenance_work_mem
value: "{{ (ansible_memtotal_mb / 16) | int }}MB"
- option: io_method
value: io_uring
- option: huge_pages
value: try
- option: random_page_cost
value: 1
- option: log_filename
value: postgresql-%Y-%m-%d.log
- option: autovacuum
value: "on"
- option: vacuum_truncate
value: "on"
- option: wal_level
value: logical
- option: wal_sync_method
value: fdatasync
- option: wal_compression
value: lz4
- option: wal_buffers
value: "{{ ((ansible_memtotal_mb / 16) | int ) if (ansible_memtotal_mb / 16) < 16 else 16 }}MB"
- option: checkpoint_completion_target
value: "0.9"
- option: max_wal_size
value: 10GB
- option: min_wal_size
value: 50MB
- option: max_wal_senders
value: 15
- option: max_replication_slots
value: 30
- option: timezone
value: Europe/Moscow
- option: timescaledb.enable_vectorized_aggregation
value: "off"

View file

@ -0,0 +1,11 @@
{{ ansible_managed | comment }}
# PostgreSQL Client Authentication Configuration File
# ===================================================
#
# See: https://www.postgresql.org/docs/current/static/auth-pg-hba-conf.html
# TYPE DATABASE USER ADDRESS METHOD
local all postgres peer
{% for client in postgresql_hba_entries %}
{{ client.type.ljust(10) }} {{ client.database.ljust(15) }} {{ client.user.ljust(15) }} {%if client.address is defined %} {{ client.address.ljust(20)|default('') }} {% endif %} {% if client.ip_address is defined %} {{ client.ip_address.ljust(20)|default('') }} {% endif %} {{ client.ip_mask|default('') }} {{ client.auth_method.ljust(10) }} {{ client.auth_options|default("") }}
{% endfor %}

View file

@ -0,0 +1,2 @@
export PGDATA={{ postgresql_data_dir }}
export PATH=$PATH:{{ postgresql_bin_path }}

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "9.2"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs

View file

@ -0,0 +1,8 @@
---
__postgresql_version: "14"
__postgresql_data_dir: /var/lib/postgres/data
__postgresql_bin_path: /usr/sbin
__postgresql_config_path: /var/lib/postgres/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql

View file

@ -0,0 +1,12 @@
---
__postgresql_version: "11"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql@{{ postgresql_version }}-main
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
# Debian 10 uses Python 3 by default.
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "13"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql@{{ __postgresql_version }}-main
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "15"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql@{{ postgresql_version }}-main
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "17"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql@{{ postgresql_version }}-main
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,10 @@
---
__postgresql_version: "9.6"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql@{{ postgresql_version }}-main
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "13.4"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "13.4"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "14.1"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "14.3"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "15.1"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "15.6"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "16.3"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "16.3"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "16.8"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,14 @@
---
__postgresql_version: "18.1"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs
__postgresql_unix_socket_directories_mode: "0755"
# Fedora 32 containers only have python3 by default
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "9.2"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
- postgresql-libs

View file

@ -0,0 +1,12 @@
---
__postgresql_version: "10"
__postgresql_data_dir: /var/lib/pgsql/data
__postgresql_bin_path: /usr/bin
__postgresql_config_path: /var/lib/pgsql/data
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-server
- postgresql-contrib
__postgresql_unix_socket_directories_mode: "0755"
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,12 @@
---
__postgresql_version: "13"
__postgresql_data_dir: /var/lib/pgsql/{{ postgresql_version | default('fallback', true) }}/data
__postgresql_bin_path: /usr/pgsql-{{ postgresql_version | default('fallback', true) }}/bin
__postgresql_config_path: /var/lib/pgsql/{{ postgresql_version | default('fallback', true) }}/data
__postgresql_daemon: postgresql-{{ postgresql_version | default('fallback', true) }}
__postgresql_packages:
- postgresql{{ postgresql_version | default('fallback', true) }}
- postgresql{{ postgresql_version | default('fallback', true) }}-server
- postgresql{{ postgresql_version | default('fallback', true) }}-contrib
__postgresql_unix_socket_directories_mode: "0755"
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,10 @@
---
__postgresql_version: "9.5"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "10"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "12"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "14"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "16"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -0,0 +1,11 @@
---
__postgresql_version: "18"
__postgresql_data_dir: /var/lib/postgresql/{{ __postgresql_version }}/main
__postgresql_bin_path: /usr/lib/postgresql/{{ __postgresql_version }}/bin
__postgresql_config_path: /etc/postgresql/{{ __postgresql_version }}/main
__postgresql_daemon: postgresql
__postgresql_packages:
- postgresql
- postgresql-contrib
- libpq-dev
postgresql_python_library: python3-psycopg2

View file

@ -17,4 +17,4 @@
ansible.builtin.file: ansible.builtin.file:
src: '{{ etc_freeradius }}/mods-config/files/authorize' src: '{{ etc_freeradius }}/mods-config/files/authorize'
dest: '{{ etc_freeradius }}/users' dest: '{{ etc_freeradius }}/users'
state: link state: link

View file

@ -3,7 +3,7 @@
when: ansible_os_family == "Debian" when: ansible_os_family == "Debian"
ansible.builtin.apt: ansible.builtin.apt:
name: python3-pymysql name: python3-pymysql
update_cache: yes update_cache: true
state: present state: present
- name: Install python packages - name: Install python packages
@ -52,19 +52,19 @@
name: "{{ radius_db_name }}" name: "{{ radius_db_name }}"
state: import state: import
target: /etc/raddb/mods-config/sql/main/mysql/schema.sql target: /etc/raddb/mods-config/sql/main/mysql/schema.sql
#target: "{{ radius_sql.dest }}" # target: "{{ radius_sql.dest }}"
- name: Restore database - name: Restore database
when: ansible_distribution == "OracleLinux" and db_type == "mariadb" when: ansible_distribution == "OracleLinux" and db_type == "mariadb"
ansible.builtin.shell: mariadb --skip_ssl -h {{ db_login_host }} -u root -p{{ db_root_password | trim }} {{ radius_db_name }} < /etc/raddb/mods-config/sql/main/mysql/schema.sql ansible.builtin.shell: mariadb --skip_ssl -h {{ db_login_host }} -u root -p{{ db_root_password | trim }} {{ radius_db_name }} < /etc/raddb/mods-config/sql/main/mysql/schema.sql
#- name: Run several insert queries against db test_db in single transaction # - name: Run several insert queries against db test_db in single transaction
# when: (db_login_host is defined) and (db_login_host|length > 0) # when: (db_login_host is defined) and (db_login_host|length > 0)
# community.mysql.mysql_query: # community.mysql.mysql_query:
# login_host: "{{ db_login_host }}" # login_host: "{{ db_login_host }}"
# login_user: "{{ radius_db_user }}" # login_user: "{{ radius_db_user }}"
# login_password: "{{ radius_db_password | trim }}" # login_password: "{{ radius_db_password | trim }}"
# login_db: "{{ radius_db_name }}" # login_db: "{{ radius_db_name }}"
# query: # query:
# - INSERT IGNORE INTO {{ radius_db_name }}.radcheck (username, attribute, op, value) VALUES ('ismail', 'Cleartext-Password', ':=', 'meknes79!') # - INSERT IGNORE INTO {{ radius_db_name }}.radcheck ...
# single_transaction: yes # single_transaction: true

View file

@ -7,8 +7,8 @@ net.ipv4.conf.j2.default.accept_source_route = 0
# Если в таблице маршрутизации есть маршрут на сеть, с которой пришёл пакет (src ip) # Если в таблице маршрутизации есть маршрут на сеть, с которой пришёл пакет (src ip)
# и он ссылается на данный интерфейс, то такой пакет будет принят. # и он ссылается на данный интерфейс, то такой пакет будет принят.
# остальные будут отброшены. # остальные будут отброшены.
net.ipv4.conf.j2.default.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.j2.all.rp_filter=1 net.ipv4.conf.all.rp_filter=1
net.ipv4.conf.j2.lo.rp_filter=1 net.ipv4.conf.lo.rp_filter=1
net.ipv4.all.send_redirects=0 net.ipv4.all.send_redirects=0
net.ipv4.all.accept_redirects=0 net.ipv4.all.accept_redirects=0

View file

@ -0,0 +1,21 @@
---
policy_routing_fwmark: 53
policy_routing_table_id: 53
policy_routing_table_name: dns-via-balancer
policy_routing_gateways: [] # список IP балансировщиков, обязательно
policy_routing_protocols: # протоколы, чьи ответы маркировать
- udp # DNS over UDP (основной транспорт)
- tcp # DNS over TCP (truncation fallback, большие ответы)
policy_routing_src_port: 53
policy_routing_rp_filter_mode: 2 # 2=loose, нужен для transparent proxy
policy_routing_local_routes: [] # маршруты в таблицу dns-via-balancer (напр. connected-сети)
policy_routing_interface: ens192 # интерфейс для -m mac PREROUTING
# Режим MAC-matching (непустой список → MAC-режим, пустой → ECMP)
# Формат каждого элемента:
# ip: IP-адрес балансировщика (шлюз в таблице маршрутизации)
# mac: MAC-адрес ens192 балансировщика (lowercase, с двоеточиями)
# table_id: уникальный ID таблицы маршрутизации (53, 54, ...)
# table_name: имя таблицы в rt_tables
# fwmark: значение fwmark для ip rule (должно совпадать с set-mark)
policy_routing_balancers: []

View file

@ -0,0 +1,12 @@
---
- name: Restart policy-routing
ansible.builtin.systemd:
name: policy-routing.service
daemon_reload: true
state: restarted
enabled: true
- name: Reload firewalld
ansible.builtin.service:
name: firewalld
state: reloaded

View file

@ -0,0 +1,16 @@
---
- name: "CONNMARK PREROUTING {{ balancer.mac }} proto={{ proto }}"
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --add-rule
ipv4 mangle PREROUTING 0
-i {{ policy_routing_interface }}
-m mac --mac-source {{ balancer.mac }}
-p {{ proto }} --dport {{ policy_routing_src_port }}
-j CONNMARK --set-mark {{ balancer.fwmark }}
register: result
changed_when: "'ALREADY_ENABLED' not in result.stderr"
notify: Reload firewalld
loop: "{{ policy_routing_protocols }}"
loop_control:
loop_var: proto

View file

@ -0,0 +1,108 @@
---
- name: Добавить таблицу маршрутизации в rt_tables
ansible.builtin.lineinfile:
path: /etc/iproute2/rt_tables
line: "{{ policy_routing_table_id }}\t{{ policy_routing_table_name }}"
regexp: "^{{ policy_routing_table_id }}\\s"
owner: root
group: root
mode: "0644"
create: true
- name: Установить rp_filter в loose mode
ansible.posix.sysctl:
name: "{{ item }}"
value: "{{ policy_routing_rp_filter_mode }}"
sysctl_file: /etc/sysctl.d/50-policy-routing.conf
reload: true
loop:
- net.ipv4.conf.all.rp_filter
- net.ipv4.conf.default.rp_filter
- name: Установить/обновить systemd unit policy-routing
ansible.builtin.template:
src: policy-routing.service.j2
dest: /etc/systemd/system/policy-routing.service
owner: root
group: root
mode: "0644"
notify: Restart policy-routing
- name: Включить и запустить policy-routing
ansible.builtin.systemd:
name: policy-routing
enabled: true
state: started
masked: false
daemon_reload: true
# ── ECMP-режим: маркировка OUTPUT (только если policy_routing_balancers пустой) ─
- name: Маркировать исходящие DNS-ответы (ECMP-режим)
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --add-rule
ipv4 mangle OUTPUT 0 -p {{ item }} --sport {{ policy_routing_src_port }}
-j MARK --set-xmark {{ policy_routing_fwmark }}
loop: "{{ policy_routing_protocols }}"
register: result
changed_when: "'ALREADY_ENABLED' not in result.stderr"
notify: Reload firewalld
when: policy_routing_balancers | length == 0
# ── MAC-matching режим ───────────────────────────────────────────────────────
- name: MAC-matching режим
when: policy_routing_balancers | length > 0
block:
- name: Добавить дополнительные таблицы маршрутизации в rt_tables
ansible.builtin.lineinfile:
path: /etc/iproute2/rt_tables
line: "{{ item.table_id }}\t{{ item.table_name }}"
regexp: "^{{ item.table_id }}\\s"
owner: root
group: root
mode: "0644"
create: true
loop: "{{ policy_routing_balancers }}"
- name: Удалить старое правило MARK OUTPUT (несовместимо с CONNMARK)
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --remove-rule
ipv4 mangle OUTPUT 0 -p {{ item }} --sport {{ policy_routing_src_port }}
-j MARK --set-xmark {{ policy_routing_fwmark }}
loop: "{{ policy_routing_protocols }}"
register: remove_result
failed_when: false
changed_when: remove_result.rc == 0
notify: Reload firewalld
- name: Добавить CONNMARK PREROUTING по MAC для каждого балансировщика
ansible.builtin.include_tasks: connmark-prerouting.yml
loop: "{{ policy_routing_balancers }}"
loop_control:
loop_var: balancer
- name: Добавить CONNMARK restore в OUTPUT (UDP)
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --add-rule
ipv4 mangle OUTPUT 0
-p udp --sport {{ policy_routing_src_port }}
-m connmark ! --mark 0
-j CONNMARK --restore-mark
register: result
changed_when: "'ALREADY_ENABLED' not in result.stderr"
notify: Reload firewalld
- name: Добавить CONNMARK restore в OUTPUT (TCP)
ansible.builtin.command:
cmd: >
firewall-cmd --permanent --direct --add-rule
ipv4 mangle OUTPUT 0
-p tcp --sport {{ policy_routing_src_port }}
-m connmark ! --mark 0
-j CONNMARK --restore-mark
register: result
changed_when: "'ALREADY_ENABLED' not in result.stderr"
notify: Reload firewalld

View file

@ -0,0 +1,53 @@
[Unit]
Description=Policy routing — DNS ответы через балансировщики
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
RemainAfterExit=yes
{% if policy_routing_balancers | length > 0 %}
# Режим MAC-matching: отдельная таблица и правило для каждого балансировщика
{% for balancer in policy_routing_balancers %}
ExecStartPre=-/usr/sbin/ip rule del fwmark {{ balancer.fwmark }} table {{ balancer.table_id }} priority {{ 100 + loop.index0 }}
ExecStartPre=-/usr/sbin/ip route flush table {{ balancer.table_id }}
{% endfor %}
{% for balancer in policy_routing_balancers %}
ExecStart=/usr/sbin/ip rule add fwmark {{ balancer.fwmark }} table {{ balancer.table_id }} priority {{ 100 + loop.index0 }}
ExecStart=/usr/sbin/ip route add default table {{ balancer.table_id }} via {{ balancer.ip }}
{% endfor %}
{% for route in policy_routing_local_routes %}
{% for balancer in policy_routing_balancers %}
ExecStart=/usr/sbin/ip route add {{ route }} table {{ balancer.table_id }}
{% endfor %}
{% endfor %}
{% for balancer in policy_routing_balancers %}
ExecStop=-/usr/sbin/ip rule del fwmark {{ balancer.fwmark }} table {{ balancer.table_id }} priority {{ 100 + loop.index0 }}
ExecStop=-/usr/sbin/ip route flush table {{ balancer.table_id }}
{% endfor %}
{% else %}
# Режим ECMP (обратная совместимость: один или несколько балансировщиков без MAC)
ExecStartPre=-/usr/sbin/ip rule del fwmark {{ policy_routing_fwmark }} table {{ policy_routing_table_id }} priority 100
ExecStartPre=-/usr/sbin/ip route flush table {{ policy_routing_table_id }}
ExecStart=/usr/sbin/ip rule add fwmark {{ policy_routing_fwmark }} table {{ policy_routing_table_id }} priority 100
ExecStart=/usr/sbin/ip route add default table {{ policy_routing_table_id }} \
{% for gw in policy_routing_gateways %}
nexthop via {{ gw }} weight 1 {% if not loop.last %} \{% endif %}
{% endfor %}
{% for route in policy_routing_local_routes %}
ExecStart=/usr/sbin/ip route add {{ route }} table {{ policy_routing_table_id }}
{% endfor %}
ExecStop=-/usr/sbin/ip rule del fwmark {{ policy_routing_fwmark }} table {{ policy_routing_table_id }} priority 100
{% for route in policy_routing_local_routes %}
ExecStop=-/usr/sbin/ip route del {{ route }} table {{ policy_routing_table_id }}
{% endfor %}
ExecStop=-/usr/sbin/ip route flush table {{ policy_routing_table_id }}
{% endif %}
[Install]
WantedBy=multi-user.target

View file

@ -0,0 +1,707 @@
Zabbix agent role
=================
You can use this Ansible role to deploy and configure Zabbix agents on the target machines. Both agentd and agent2 variants are available.
Currently, the following OS of target machines are supported:
- Redhat 8, 9, 10
- Oracle Linux 8, 9
- Alma Linux 8, 9
- Rocky Linux 8, 9
- CentOS Stream 9, 10
- Ubuntu 20.04, 22.04, 24.04
- Debian 10, 11, 12
- Raspberry Pi Os: 11, 12
Supported distribution list to be extended.
**Note**: This role is still in active development. There may be unidentified issues and the role variables may change as development continues.
Table of contents
-----------------
<!--ts-->
* [Requirements](#requirements)
* [Role variables](#role-variables)
* [General settings](#general-settings)
* [User settings](#user-settings)
* [Firewall settings](#firewall-settings)
* [Logrotate configuration for Zabbix agent](#logrotate-configuration-for-zabbix-agent)
* [Local path settings](#local-path-variables-table)
* [SELinux settings](#selinux-settings)
* [Common Zabbix agent configuration file parameters](#common-zabbix-agent-configuration-parameters)
* [Zabbix agent unique parameters](#zabbix-agentd-unique-parameters)
* [Zabbix agent 2 unique parameters](#zabbix-agent-2-unique-parameters)
* [Ceph plugin parameters](#zabbix-agent-2-ceph-plugin-parameters)
* [Docker plugin parameters](#zabbix-agent-2-docker-plugin-parameters)
* [Memcached plugin parameters](#zabbix-agent-2-memcached-plugin-parameters)
* [Modbus plugin parameters](#zabbix-agent-2-modbus-plugin-parameters)
* [MongoDB plugin parameters](#zabbix-agent-2-mongodb-plugin-parameters)
* [MQTT plugin parameters](#zabbix-agent-2-mqtt-plugin-parameters)
* [Oracle plugin parameters](#zabbix-agent-2-oracle-plugin-parameters)
* [PostgreSQL plugin parameters](#zabbix-agent-2-postgresql-plugin-parameters)
* [MySQL plugin parameters](#zabbix-agent-2-mysql-plugin-parameters)
* [MSSQL plugin parameters](#zabbix-agent-2-mssql-plugin-parameters)
* [NVIDIA GPU plugin parameters](#zabbix-agent-2-nvidia-gpu-plugin-parameters)
* [Redis plugin parameters](#zabbix-agent-2-redis-plugin-parameters)
* [Smart plugin parameters](#zabbix-agent-2-smart-plugin-parameters)
* [Hints & Tags](#hints--tags)
* [Playbook examples](#playbook-examples)
* [Playbook 1: Latest LTS Zabbix agentd deployment for active checks only](#playbook-1)
* [Playbook 2: 6.4 version of Zabbix agent 2 for both passive and active checks + Iptables](#playbook-2)
* [Playbook 3: Zabbix agentd for both passive and active checks with PSK encryption for autoregistration](#playbook-3)
* [Playbook 4: Zabbix agentd with certificate-secured connections](#playbook-4)
* [Playbook 5: 6.4 version of Zabbix agent 2 for MongoDB monitoring](#playbook-5)
* [Playbook 6: Zabbix agentd downgrade from 6.4 to 6.0](#playbook-6)
* [Playbook 7: Zabbix agentd running under custom user](#playbook-7)
* [Playbook 8: Update Zabbix agentd to the latest minor version](#playbook-8)
* [Playbook 9: Deploy Zabbix agentd without direct internet access, by using HTTP proxy](#playbook-9)
* [Playbook 10: Deploy Zabbix agent with passive checks only and add hosts to Zabbix](#playbook-10)
* [License](#license)
<!--te-->
Requirements
------------
This role uses official Zabbix packages and repository for component installation. Target machines require direct or [**HTTP proxy**](#playbook-9) internet access to Zabbix repository [**repo.zabbix.com**](https://repo.zabbix.com).
For self-hosted repository mirrors, override URL for [`agent_repository_mirror`](#general-settings) variable.
The role contains firewalld application rule to allow agent listen port. Firewalld is required on the target machines for this rule to work. Automatic mode `agent_apply_firewalld_rule = auto` checks if firewalld is installed. Firewalld is a recommended method as it can work with both iptables and nftables. Firewalld can be installed on RHEL- and Debian-based distributions.
Multiple tasks require `superuser` privileges (sudo).
Ansible core >= 2.17
Zabbix agent role requires additional tools from two Ansible certified collections:
- ansible.posix >= 2.8
- ansible.utils >= 1.4
You can install required collections easily:
```bash
ansible-galaxy collection install ansible.utils ansible.posix
```
Note that the role uses [**ansible.utils.ipaddr**](https://docs.ansible.com/ansible/latest/collections/ansible/utils/docsite/filters_ipaddr.html) filter, which depends on Python library [**netaddr**](https://pypi.org/project/netaddr).
Zabbix agent role relies on [**Jinja2**](https://pypi.org/project/Jinja2/) heavily and requires version >= 3.1.2
You can install required Python libraries on the control node as follows:
```bash
python3 -m pip install "netaddr>=0.8.0" "Jinja2>=3.1.2"
```
Or using `requirements.txt` file in the role folder:
```bash
python3 -m pip install -r requirements.txt
```
Check the [**Python documentation**](https://docs.python.org/3/installing/index.html) for more details on Python modules installation.
SELinux tasks depend on `policycoreutils` package. It will be installed as dependency with `zabbix-selinux-policy` package.
Note that Ansible-core 2.17 requires at least python3.7 on the target devices. Check the [**compatibility matrix**](https://docs.ansible.com/ansible/latest/reference_appendices/release_and_maintenance.html#ansible-core-support-matrix) for other versions.
Role variables
--------------
You can modify variables listed in this section. Variables are not validated by the role itself. You should experiment with variable definition on a test instance before going for a full-scale deployment.
The default settings are aimed at the ease of installation. You can override those to improve security.
### General settings:
| Variable | Type | Default | Description |
|--|--|--|--|
| agent_variant | `int` | 1 | The variant of Zabbix agent (1: Zabbix agentd, 2: Zabbix agent 2).
| agent_major_version | `string` | 6.0 | The major version of Zabbix agent. Defaults to the latest LTS.
| agent_minor_version | `string` || Zabbix agent minor version customization. For downgrade use with `agent_remove_previous_packages=true`. Minor version example for debian family distributions: `25-1` (minor version - package version). For RHEL family: `25` (minor version). In both cases minor version will be applied to all packages in `agent_package_list`.
| agent_package_state | `string` | present | The state of packages to be deployed. Available options: `present`, `latest` - update to the latest version if available in the installed **zabbix-managed** repository.
| agent_remove_previous_packages | `boolean` | `false` | Trigger removal of previous packages prior to the installation of the new ones. Mandatory to deploy earlier version than the one currently installed.
| agent_2_plugin_list | `list` | [ceph, docker, memcached, modbus, mongodb, mqtt, mysql, oracle, postgresql, redis, smart] | List of Zabbix agent 2 plugins to configure and deploy (if the plugin is loadable). **Note** that loadable plugins for 6.0 version are installed as dependencies of Zabbix agent 2 package. Starting with 6.4, loadable plugin installation is allowed at your own discretion. Default plugin list for Zabbix agent 2 >= **6.4** is `[ceph, docker, memcached, modbus, mqtt, mysql, oracle, redis, smart]`.
| agent_http_proxy | `string` || Defines [**HTTP proxy**](#playbook-9) address for the packager.
| agent_https_proxy | `string` || Defines HTTPS proxy address for the packager.
| agent_repository_mirror | `string` | "https://repo.zabbix.com/" | Defines repository mirror URL. You can override it to use self-hosted Zabbix repo mirror.
| agent_repository_priority | `int` | 99 | **For RedHat family OS only.** Sets the priority of the Zabbix repository. Expects integer values from 1 to 99. Covers the cases with interfering packages from central distribution repositories.
| agent_repository_disable | `string` | "epel" | **For RedHat family OS only.** Disables defined repository during package deployment. Disables EPEL by default.
### User settings:
The role allows creating a custom user for Zabbix agent. User customization tasks will trigger only when `agent_service_user` is not "zabbix".
| Variable | Type | Default | Description |
|--|--|--|--|
| agent_service_user | `string` | zabbix | The user to run Zabbix agent.
| agent_service_group | `string` | zabbix | User group for the custom user.
| agent_service_uid | `string` || User ID for the custom user.
| agent_service_gid | `string` || User group ID for the custom user group.
Adds next task sequence:
- Creates group.
- Creates user with home folder (defaults to `/home/{{ agent_service_user }}`).
- Adds **systemd** overrides to manage Zabbix agent pid file (`/run/zabbix_agent[d|2]/zabbix_agent[d|2].pid`).
- Changes Zabbix agent 2 sockets paths (to the folder of pid file).
- Changes logging path (to `/var/log/zabbix_agent[d|2]/zabbix_agent[d|2].log`).
### Firewall settings:
The role allows adding simple firewall rules on the target machine to accept passive checks. Advanced firewall configuration is out of the scope of Zabbix agent role.
Firewalld is a recommended way of applying firewall rule as it works with both iptables and nftables. **Note** that `iptables` does not work in Ubuntu since 22.04. Firewalld should be installed on target machines. It is supported on RHEL- and Debian-based distributions.
| Variable | Type | Default | Description |
|--|--|--|--|
| agent_apply_firewalld_rule | `string` | `false` | Defines application of firewalld rule. Possible options: ["auto", "force"]. Undefined or any other string will skip the rule application.
| agent_apply_iptables_rule | `boolean` | `false` | Defines application of iptables rule. Possible options: [true, false].
| agent_firewalld_zone | `string` | default | Firewalld zone for the rule application.
| agent_firewall_allow_from | `string` || Only IP addresses allowed. Limits source address of passive check using the firewall rule. For firewalld, this setting will change the rule from simple to rich rule.
***You can notice Python module "firewall" sometimes failing to import during these tasks. Most common issue is that Ansible chooses wrong Python interpreter from multiple versions available on host. A solution to this is to provide `ansible_python_interpreter` with a correct path to legit Python installation on target hosts for specific operating systems. Normally it is defined on inventory level.***
### **Logrotate** configuration for Zabbix agent
You can modify rotation options of Zabbix agent[2] log file. It requires default option overriding in `agent_logrotate_options` variable.
This is a `list` type variable, and it defaults to the list of the following options:
- weekly
- maxsize 5M
- rotate 12
- compress
- delaycompress
- missingok
- notifempty
- create 0640 {{ agent_service_user }} {{ agent_service_group }}
**Note** that most distributions execute logrotate jobs on a daily basis by default. If you wish to change rotation calendar, modify cronjob or systemd timer accordingly or add separate cronjob/timer to process only Zabbix agent[2] log.
### Local path variables table:
Variables prefixed with `source_` should point to a file or folder located on Ansible execution environment. These files are about to be transferred to the target machines.
| Variable | Type | Default | Description |
|--|--|--|--|
| agent_source_conf_dir | `string` || Path to the configuration folder on Ansible execution environment that needs to be transferred to the target machine and included in Zabbix agent configuration. For example, a folder with `Userparameters`.
| agent_source_scripts_dir | `string` || Path to the scripts folder on Ansible execution environment. Will be copied under the `agent_service_user` home folder. Scripts can be utilized by `UserParameters`.
| agent_source_modules_dir | `string` || Path to Zabbix agentd modules folder on Ansible execution environment. Will be copied to default location for default user. For custom user modules, will be placed under the `agent_service_user` home folder.
| agent_source_tlspskfile | `string` | `.PSK/{{ inventory_hostname }}.psk` | Path to the PSK key location on Ansible execution environment. The role will look for the files having the same names as `inventory_hostname` (hostname from inventory) and generate new if not found. This key will be placed under `agent_service_user` home folder and added to Zabbix agent configuration automatically.
| agent_source_tlscafile | `string` || Path to the file on Ansible execution environment containing the top-level CA(s) certificates for peer certificate verification. Will be placed under `agent_service_user` home folder and added to Zabbix agent configuration automatically.
| agent_source_tlscertfile | `string` || Path to the file on Ansible execution environment containing the agent certificate or certificate chain. Will be placed under `agent_service_user` home folder and added to Zabbix agent configuration automatically.
| agent_source_tlscrlfile | `string` || Path to the file on Ansible execution environment containing revoked certificates. Will be placed under `agent_service_user` home folder and added to Zabbix agent configuration automatically.
| agent_source_tlskeyfile | `string` || Path to the file containing the agent private key. Will be placed under `agent_service_user` home folder and added to Zabbix agent configuration automatically.
### SELinux settings:
SELinux tasks will be processed only when SELinux status on the target machine is `enabled`
SELinux tasks depend on `policycoreutils` package. It will be installed as dependency with `zabbix-selinux-policy` package.
| Variable | Type | Default | Description |
|--|--|--|--|
| agent_apply_seport | `boolean` | `true` | Adds custom agent port defined in `agent_param_listenport` to SELinux port type `zabbix_agent_port_t`. Enabled by default and triggers when `agent_param_listenport` is not equal to 10050.
| agent_apply_semodule | `boolean` | `false` | Adds SELinux policy extension to make a transition of Zabbix agent 2 to SE domain `zabbix_agent_t`. Additionally, it allows socket usage for the same domain. It also enables read permission on RPM database for `system.sw.packages.get` key.
| agent_seboolean_zabbix_run_sudo | `string` || Enables/disables default SELinux boolean `zabbix_run_sudo`. For task processing, expects string values "on" or "off". Undefined by default, in order to skip task processing. Use with caution as it holds allow rules for a set of domains.
Why `audit2allow` tool is not included in the role:
- not secure (it just allows everything that was denied);
- requires several days of auditlog to collect all needed denials.
Use it only as a policy creation consultant.
Default SE boolean `zabbix_run_sudo` does not fit all possible privileged usage and should be avoided in most cases.
Create custom policies for environments with specific security requirements.
### Common Zabbix agent configuration parameters:
These parameters are common for both agent variants
| Variable | Type | Default | Parameter | Description |
|--|--|--|--|--|
| agent_param_alias | `list` || [**Alias**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#alias) | Set an alias for the item key. Location of aliases on target machine: `/etc/zabbix/zabbix_agent[d|2].d/aliases.conf`
| agent_param_allowkey | `list` || [**AllowKey**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#allowkey) | Allow execution of the item keys that match the pattern.
| agent_param_buffersend | `int` || [**BufferSend**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#buffersend) | Do not keep data in the buffer longer than N seconds.
| agent_param_buffersize | `int` || [**BufferSize**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#buffersize) | Maximum number of values in the memory buffer.
| agent_param_debuglevel | `int` || [**DebugLevel**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#debuglevel) | Debug level.
| agent_param_denykey | `list` || [**DenyKey**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#denykey) | Deny execution of the item keys that match the pattern.
| agent_param_heartbeatfrequency | `int` || [**HeartbeatFrequency**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#heartbeatfrequency) | Frequency of the heartbeat messages in seconds. Added in 6.4.
| agent_param_hostinterface | `string` || [**HostInterface**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#hostinterface) | Optional parameter that defines the host interface.
| agent_param_hostinterfaceitem | `string` || [**HostInterfaceItem**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#hostinterfaceitem) | Optional parameter that defines the item used for getting the host interface.
| agent_param_hostmetadata | `string` || [**HostMetadata**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#hostmetadata) | Optional parameter that defines the host metadata.
| agent_param_hostmetadataitem | `string` || [**HostMetadataItem**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#hostmetadataitem) | Optional parameter that defines Zabbix agent item used for getting the host metadata.
| agent_param_hostname | `string` | `{{inventory_hostname}}` | [**Hostname**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#hostname) | Optional parameter that defines the hostname. Defaults to the hostname taken from the inventory.
| agent_param_hostnameitem | `string` || [**HostnameItem**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#hostnameitem) | Optional parameter that defines Zabbix agent item used for getting the hostname.
| agent_param_include | `list` | **agentd:** ["/etc/zabbix/zabbix_agentd.d/\*.conf"] **agent2:** ["/etc/zabbix/zabbix_agent2.d/\*.conf"] | [**Include**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#include) | You may include individual files or all files in a directory in the configuration file.
| agent_param_listenip | `string` || [**ListenIP**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#listenip) | List of comma-delimited IP addresses that the agent should listen on.
| agent_param_listenport | `int` || [**ListenPort**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#listenport) | The agent will listen on this port for connections from the server.
| agent_param_logfile | `string` | **agentd:** /var/log/zabbix/zabbix_agentd.log **agent2:** /var/log/zabbix/zabbix_agent2.log | [**LogFile**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#logfile) | Name of the log file.
| agent_param_logfilesize | `int` | 0 | [**LogFileSize**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#logfilesize) | Maximum size of the log file.
| agent_param_logtype | `string` | file | [**LogType**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#logtype) | Type of the log output.
| agent_param_pidfile | `string` | **agentd:** /run/zabbix/zabbix_agentd.pid **agent2:** /run/zabbix/zabbix_agent2.pid | [**PidFile**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#pidfile) | Name of the PID file.
| agent_param_refreshactivechecks | `int` || [**RefreshActiveChecks**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#refreshactivechecks) | How often the list of active checks is refreshed.
| agent_param_server | `string` | ::/0 | [**Server**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#server) | List of comma-delimited IP addresses, optionally in CIDR notation, or hostnames of Zabbix servers and Zabbix proxies.
| agent_param_serveractive | `string` || [**ServerActive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#serveractive) | Zabbix server/proxy address or cluster configuration to get the active checks from.
| agent_param_sourceip | `string` || [**SourceIP**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#sourceip) | Source IP address.
| agent_param_timeout | `int` || [**Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#timeout) | Spend no more than Timeout seconds on processing.
| agent_param_tlsaccept | `list` | ["unencrypted"] | [**TLSAccept**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlsaccept) | Incoming connections to be accepted. Available options: `unencrypted`, `cert`, `psk`.
| agent_param_tlsconnect | `string` | unencrypted | [**TLSConnect**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlsconnect) | How the agent should connect to Zabbix server or proxy. Available options: `unencrypted`, `cert`, `psk`.
| agent_param_tlscafile | `string` || [**TLSCAFile**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlscafile) | Path to the top-level CA(s) certificates for peer certificate verification. Use only when [`agent_source_tlscafile`](#local-paths-variables-table) is not defined!
| agent_param_tlscertfile | `string` || [**TLSCertFile**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlscertfile) | Path to the agent certificate or certificate chain. Use only when [`agent_source_tlscertfile`](#local-paths-variables-table) is not defined!
| agent_param_tlscrlfile | `string` || [**TLSCRLFile**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlscrlfile) | Path to revoked certificates. Use only when [`agent_source_tlscrlfile`](#local-paths-variables-table) is not defined!
| agent_param_tlscipherall | `string` || [**TLSCipherAll**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlscipherall) | Override the default ciphersuite selection criteria for certificate- and PSK-based encryption.
| agent_param_tlscipherall13 | `string` || [**TLSCipherAll13**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlscipherall13) | Override the default ciphersuite selection criteria for certificate- and PSK-based encryption.
| agent_param_tlsciphercert | `string` || [**TLSCipherCert**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlsciphercert) | Override the default ciphersuite selection criteria for certificate-based encryption.
| agent_param_tlsciphercert13 | `string` || [**TLSCipherCert13**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlsciphercert13) | Override the default ciphersuite selection criteria for certificate-based encryption.
| agent_param_tlscipherpsk | `string` || [**TLSCipherPSK**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlscipherpsk) | Override the default ciphersuite selection criteria for PSK-based encryption.
| agent_param_tlscipherpsk13 | `string` || [**TLSCipherPSK13**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlscipherpsk13) | Override the default ciphersuite selection criteria for PSK-based encryption.
| agent_param_tlskeyfile | `string` || [**TLSKeyFile**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlskeyfile) | Path to the agent private key. Use only when [`agent_source_tlskeyfile`](#local-paths-variables-table) is not defined!
| agent_param_tlspskidentity | `string` | `PSK_ID_{{ inventory_hostname }}` | [**TLSPSKIdentity**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlspskidentity) | Pre-shared key identity string used for encrypted communications with Zabbix server. Default value uses prefixed hostname from inventory.
| agent_param_tlsservercertissuer | `string` || [**TLSServerCertIssuer**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlsservercertissuer) | Allowed server (proxy) certificate issuer.
| agent_param_tlsservercertsubject | `string` || [**TLSServerCertSubject**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#tlsservercertsubject) | Allowed server (proxy) certificate subject.
| agent_param_unsafeuserparameters | `int` || [**UnsafeUserParameters**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#unsafeuserparameters) | Allow all characters to be passed in arguments to user-defined parameters.
| agent_param_userparameter | `list` || [**UserParameter**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#userparameter) | User-defined parameter to monitor. Listed user parameters will be placed into the target machine folder: `/etc/zabbix/zabbix_agent[d|2].d/userparameters.conf`. If changed, this parameter triggers *userparameter reload*(agent runtime command).
| agent_param_userparameterdir | `string` || [**UserParameterDir**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#userparameterdir) | Default search path for UserParameter commands.
### Zabbix **agentd** unique parameters:
| Variable | Type | Default | Parameter | Description |
|--|--|--|--|--|
| agent_param_allowroot | `int` || [**AllowRoot**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#allowroot) | Allow the agent to run as 'root'.
| agent_param_enableremotecommands | `int` || [**EnableRemoteCommands**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#enableremotecommands) | Whether remote commands from Zabbix server are allowed.
| agent_param_listenbacklog | `int` || [**ListenBacklog**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#listenbacklog) | Maximum number of pending connections in the TCP queue.
| agent_param_loadmodule | `list` || [**LoadModule**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#loadmodule) | Module to load at agent startup.
| agent_param_loadmodulepath | `string` | /usr/lib64/zabbix/modules | [**LoadModulePath**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#loadmodulepath) | Full path to the location of agent modules.
| agent_param_logremotecommands | `int` || [**LogRemoteCommands**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#logremotecommands) | Enable logging of executed shell commands as warnings.
| agent_param_maxlinespersecond | `int` || [**MaxLinesPerSecond**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#maxlinespersecond) | Maximum number of new lines per second that the agent will send to Zabbix server or proxy when processing 'log' and 'logrt' active checks.
| agent_param_startagents | `int` || [**StartAgents**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#startagents) | Number of pre-forked instances of zabbix_agentd processing the passive checks.
| agent_param_user | `string` || [**User**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agentd#user) | Drop privileges to a specific user existing in the system.
### Zabbix **agent 2** unique parameters:
| Variable | Type | Default | Parameter | Description |
|--|--|--|--|--|
| agent_param_controlsocket | `string` | /run/zabbix/agent.sock | [**ControlSocket**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#controlsocket) | Control socket used to send runtime commands with the '-R' option.
| agent_param_enablepersistentbuffer | `int` || [**EnablePersistentBuffer**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#enablepersistentbuffer) | Enable the usage of local persistent storage for active items.
| agent_param_forceactivechecksonstart | `int` || [**ForceActiveChecksOnStart**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#forceactivechecksonstart) | Perform active checks immediately after the restart for the first received configuration.
| agent_param_persistentbufferfile | `string` || [**PersistentBufferFile**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#persistentbufferfile) | File where Zabbix agent 2 should keep the SQLite database.
| agent_param_persistentbufferperiod | `string` || [**PersistentBufferPeriod**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#persistentbufferperiod) | Time period of storing the data when there is no connection to the server or proxy.
| agent_param_plugins_log_maxlinespersecond | `int` | `{{ agent_param_maxlinespersecond }}` | [**Plugins.Log.MaxLinesPerSecond**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#plugins.log.maxlinespersecond) | Maximum number of new lines per second to be sent by the agent to Zabbix server or proxy when processing 'log' and 'logrt' active checks. By default, works like alias to `agent_param_maxlinespersecond`.
| agent_param_plugins_systemrun_logremotecommands | `int` | `{{ agent_param_logremotecommands }}`| [**Plugins.SystemRun.LogRemoteCommands**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#plugins.systemrun.logremotecommands) | Enable the logging of the executed shell commands as warnings. By default, works like alias to `agent_param_logremotecommands`.
| agent_param_pluginsocket | `string` | /run/zabbix/agent.plugin.sock | [**PluginSocket**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#pluginsocket) | Path to the UNIX socket for loadable plugin communications.
| agent_param_plugintimeout | `int` || [**PluginTimeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#plugintimeout) | Timeout for connections with loadable plugins, in seconds.
| agent_param_refreshactivechecks | `int` || [**RefreshActiveChecks**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#refreshactivechecks) | How often the list of active checks is refreshed.
| agent_param_statusport | `int` || [**StatusPort**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#statusport) | If set, the agent will listen on this port for HTTP status requests (`http://localhost:<port>/status`).
| agent_param_includeplugins | `list` | ["/etc/zabbix/zabbix_agent2.d/plugins.d/*.conf"] | [**Include**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2#include) | Path to plugin configuration files. You may include individual files or all files in a directory in the configuration file.
### Zabbix **agent 2 Ceph plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_ceph_insecureskipverify | `string` | [**Plugins.Ceph.InsecureSkipVerify**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/ceph_plugin) | Determines whether the HTTP client should verify the server's certificate chain and host name. If true, TLS accepts any certificate presented by the server and any host name in that certificate. In this mode, TLS is susceptible to man-in-the-middle attacks (should be used only for testing).
| agent_param_plugins_ceph_keepalive | `int` | [**Plugins.Ceph.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/ceph_plugin) | Maximum time of waiting (in seconds) before unused plugin connections are closed.
| agent_param_plugins_ceph_timeout | `int` | [**Plugins.Ceph.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/ceph_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
| agent_param_plugins_ceph_sessions | `list of dictionaries` | [**Plugins.Ceph.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/ceph_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", apikey: "", user: "", uri: ""}`
| agent_param_plugins_ceph_default | `dictionary` | [**Plugins.Ceph.Default**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/ceph_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ apikey: "", user: "", uri: ""}`
### Zabbix **agent 2 Docker plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_docker_endpoint | `string` | [**Plugins.Docker.Endpoint**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/d_plugin) | Docker daemon unix-socket location. Must contain a scheme (only `unix://` is supported).
| agent_param_plugins_docker_timeout | `int` | [**Plugins.Docker.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/d_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
### Zabbix **agent 2 Memcached plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_memcached_keepalive | `int` | [**Plugins.Memcached.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/memcached_plugin) | Maximum time of waiting (in seconds) before unused plugin connections are closed.
| agent_param_plugins_memcached_timeout | `int` | [**Plugins.Memcached.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/memcached_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
| agent_param_plugins_memcached_sessions | `list of dictionaries` | [**Plugins.Memcached.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/memcached_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", password: "", user: "", uri: ""}`
| agent_param_plugins_memcached_default| `dictionary` | [**Plugins.Memcached.Default**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/memcached_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ password: "", user: "", uri: ""}`
### Zabbix **agent 2 Modbus plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_modbus_timeout | `int` | [**Plugins.Modbus.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/modbus_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
| agent_param_plugins_modbus_sessions | `list of dictionaries` | [**Plugins.Modbus.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/modbus_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", endpoint: "", slaveid: "", timeout: ""}`
### Zabbix **agent 2 MongoDB plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
To encrypt session, define `tlsconnect` key. After `tlsconnect` session key is defined, all 3 certificate files become mandatory!
Parameter prefixes `source_` should point to the certificate files located on Ansible execution environment. The certificate files will be placed on the target machine and added to configuration automatically.
You can also manage session certificate files outside this role. In this case, use same keys without `source_` prefix and fill them with final path to files on the target machine.
Here is the dictionary skeleton for self-managed certificate files:
`{ name: "", uri: "", user: "", password: "", tlsconnect: "", tlscafile: "", tlscertfile: "", tlskeyfile: ""}`
Don't use both local path and final path to avoid unpredictable results!
| Variable | Type | Default | Parameter | Description |
|--|--|--|--|--|
| agent_param_plugins_mongodb_keepalive | `int` || [**Plugins.MongoDB.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mongodb_plugin) | Maximum time of waiting (in seconds) before unused plugin connections are closed.
| agent_param_plugins_mongodb_timeout | `int` || [**Plugins.MongoDB.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mongodb_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
| agent_param_plugins_mongodb_system_path | `string` | **Zabbix version <=7.0:** /usr/sbin/zabbix-agent2-plugin/zabbix-agent2-plugin-mongodb **Zabbix version >= 7.2:** /usr/libexec/zabbix/zabbix-agent2-plugin-mongodb | [**Plugins.MongoDB.System.Path**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mongodb_plugin) | Path to external plugin executable. Supported since Zabbix 6.0.6.
| agent_param_plugins_mongodb_sessions | `list of dictionaries` || [**Plugins.MongoDB.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mongodb_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", uri: "", user: "", password: "", tlsconnect: "", source_tlscafile: "", source_tlscertfile: "", source_tlskeyfile: ""}`
| agent_param_plugins_mongodb_default | `dictionary` || [**Plugins.MongoDB.Default**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mongodb_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ uri: "", user: "", password: "",}`
### Zabbix **agent 2 MQTT plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
You can also manage session certificate files outside this role. In this case, use same keys without `source_` prefix and fill them with final path to files on the target machine.
Here is the dictionary skeleton for self-managed certificate files:
`{ name: "", url: "", topic: "", user: "", password: "", tlscafile: "", tlscertfile: "", tlskeyfile: ""}`
Don't use both local path and final path to avoid unpredictable results!
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_mqtt_timeout | `int` | [**Plugins.MQTT.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mqtt_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
| agent_param_plugins_mqtt_sessions | `list of dictionaries` | [**Plugins.MQTT.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mqtt_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", url: "", topic: "", user: "", password: "", source_tlscafile: "", source_tlscertfile: "", source_tlskeyfile: ""}`
| agent_param_plugins_mqtt_default | `dictionary` | [**Plugins.MQTT.Default**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mqtt_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ url: "", topic: "", user: "", password: "", source_tlscafile: "", source_tlscertfile: "", source_tlskeyfile: ""}`
### Zabbix **agent 2 Oracle plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_oracle_calltimeout | `int` | [**Plugins.Oracle.CallTimeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/oracle_plugin) | Maximum time of waiting (in seconds) for a request to be done.
| agent_param_plugins_oracle_connecttimeout | `int` | [**Plugins.Oracle.ConnectTimeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/oracle_plugin) | Maximum time of waiting (in seconds) for a connection to be established.
| agent_param_plugins_oracle_customqueriespath | `string` | [**Plugins.Oracle.CustomQueriesPath**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/oracle_plugin) | Full pathname of the directory containing .sql files with custom queries. Disabled by default. Example: /etc/zabbix/oracle/sql
| agent_param_plugins_oracle_keepalive | `int` | [**Plugins.Oracle.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/oracle_plugin) | Maximum time of waiting (in seconds) before unused plugin connections are closed.
| agent_param_plugins_oracle_sessions | `list of dictionaries` | [**Plugins.Oracle.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/oracle_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", uri: "", service: "", user: "", password: "" }`
| agent_param_plugins_oracle_default | `list of dictionaries` | [**Plugins.Oracle.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/oracle_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ uri: "", service: "", user: "", password: "" }`
### Zabbix **agent 2 PostgreSQL plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
To encrypt session, define `tlsconnect` key. After `tlsconnect` session key is defined, all 3 certificate files become mandatory!
Parameter prefixes `source_` should point to the certificate files located on Ansible execution environment. The certificate files will be placed on the target machine and added to configuration automatically.
You can also manage session certificate files outside this role. In this case, use same keys without `source_` prefix and fill them with final path to files on the target machine.
Here is the dictionary skeleton for self-managed certificate files:
`{ name: "", uri: "", user: "", password: "", database: "", tlsconnect: "", tlscafile: "", tlscertfile: "", tlskeyfile: "", cachemode: ""}`
Don't use both local path and final path to avoid unpredictable results!
| Variable | Type | Default | Parameter | Description |
|--|--|--|--|--|
| agent_param_plugins_postgresql_calltimeout | `int` || [**Plugins.Postgresql.CallTimeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/postgresql_plugin) | Maximum time of waiting (in seconds) for a request to be done.
| agent_param_plugins_postgresql_customqueriespath | `string` || [**Plugins.Postgresql.CustomQueriesPath**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/postgresql_plugin) | Full pathname of the directory containing .sql files with custom queries. Disabled by default. Example: /etc/zabbix/postgresql/sql
| agent_param_plugins_postgresql_keepalive | `int` || [**Plugins.Postgresql.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/postgresql_plugin) | Time of waiting (in seconds) for unused connections to be closed.
| agent_param_plugins_postgresql_timeout | `int` || [**Plugins.Postgresql.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/postgresql_plugin) | Maximum time of waiting (in seconds) for a connection to be established.
| agent_param_plugins_postgresql_system_path | `string` | **Zabbix version <=7.0:** /usr/sbin/zabbix-agent2-plugin/zabbix-agent2-plugin-postgresql **Zabbix version >= 7.2:** /usr/libexec/zabbix/zabbix-agent2-plugin-postgresql | [**Plugins.Postgresql.System.Path**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/postgresql_plugin) | Path to the external plugin executable. Supported since Zabbix 6.0.6.
| agent_param_plugins_postgresql_sessions | `list of dictionaries` || [**Plugins.Postgresql.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/postgresql_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", uri: "", user: "", password: "", database: "", tlsconnect: "", source_tlscafile: "", source_tlscertfile: "", source_tlskeyfile: "", cahcemode: ""}`
| agent_param_plugins_postgresql_default | `dictionary` || [**Plugins.Postgresql.Default**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/postgresql_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ uri: "", user: "", password: "", database: "", tlsconnect: "", source_tlscafile: "", source_tlscertfile: "", source_tlskeyfile: "", cachemode: ""}`
### Zabbix **agent 2 MySQL plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
To encrypt session, define `tlsconnect` key. After `tlsconnect` session key is defined, all 3 certificate files become mandatory!
Parameter prefixes `source_` should point to the certificate files located on Ansible execution environment. The certificate files will be placed on the target machine and added to configuration automatically.
You can also manage session certificate files outside this role. In this case, use same keys without `source_` prefix and fill them with final path to files on the target machine.
Here is the dictionary skeleton for self-managed certificate files:
`{ name: "", uri: "", user: "", password: "", tlsconnect: "", tlscafile: "", tlscertfile: "", tlskeyfile: ""}`
Don't use both local path and final path to avoid unpredictable results!
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_mysql_calltimeout | `int` | [**Plugins.Mysql.CallTimeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mysql_plugin) | Maximum time of waiting (in seconds) for a request to be done.
| agent_param_plugins_mysql_keepalive | `int` | [**Plugins.Mysql.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mysql_plugin) | Time of waiting (in seconds) before unused connections are closed.
| agent_param_plugins_mysql_timeout | `int` | [**Plugins.Mysql.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mysql_plugin) | Maximum time of waiting (in seconds) for a connection to be established.
| agent_param_plugins_mysql_customqueriespath | `string` | [**Plugins.Mysql.CustomQueriesPath**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mysql_plugin) | Full pathname of a directory containing *.sql* files with custom queries.
| agent_param_plugins_mysql_sessions | `list of dictionaries` | [**Plugins.Mysql.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mysql_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", uri: "", user: "", password: "", tlsconnect: "", source_tlscafile: "", source_tlscertfile: "", source_tlskeyfile: ""}`
| agent_param_plugins_mysql_default | `dictionary` | [**Plugins.Mysql.Default.\***](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mysql_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ uri: "", user: "", password: "", tlsconnect: "", source_tlscafile: "", source_tlscertfile: "", source_tlskeyfile: ""}`
### Zabbix **agent 2 MSSQL plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
Parameter prefixes `source_` should point to the certificate files located on Ansible execution environment. The certificate files will be placed on the target machine and added to configuration automatically.
You can also manage session certificate files outside this role. In this case, use same keys without `source_` prefix and fill them with final path to files on the target machine.
Here is the dictionary skeleton for self-managed certificate files:
`{ name: "", uri: "", user: "", password: "", cacertpath: "", trustservercertificate: "", hostnameincertificate: "", encrypt: "", tlsminversion: ""}`
Don't use both local path and final path to avoid unpredictable results!
| Variable | Type | Default | Parameter | Description |
|--|--|--|--|--|
| agent_param_plugins_mssql_keepalive | `int` || [**Plugins.MSSQL.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mssql_plugin) | Time of waiting (in seconds) before unused connections are closed.
| agent_param_plugins_mssql_timeout | `int` || [**Plugins.MSSQL.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mssql_plugin) | The amount of time to wait for a server to respond when first connecting and on follow-up operations in the session.
| agent_param_plugins_mssql_customqueriespath | `string` || [**Plugins.MSSQL.CustomQueriesPath**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mssql_plugin) | Full pathname of a directory containing *.sql* files with custom queries. Changes requires Zabbix agent2 restart.
| agent_param_plugins_mssql_system_path | `string` | **Zabbix version <=7.0:** /usr/sbin/zabbix-agent2-plugin/zabbix-agent2-plugin-mssql **Zabbix version >= 7.2:** /usr/libexec/zabbix/zabbix-agent2-plugin-mssql | [**Plugins.MSSQL.System.Path**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mssql_plugin) | Path to the external plugin executable.
| agent_param_plugins_mssql_sessions | `list of dictionaries` || [**Plugins.MSSQL.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mssql_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", uri: "", user: "", password: "", source_cacertpath: "", trustservercertificate: "", hostnameincertificate: "", encrypt: "", tlsminversion: ""}`
| agent_param_plugins_mssql_default | `dictionary` || [**Plugins.MSSQL.Default.\***](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/mssql_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ uri: "", user: "", password: "", source_cacertpath: "", trustservercertificate: "", hostnameincertificate: "", encrypt: "", tlsminversion: ""}`
### Zabbix **agent 2 NVIDIA GPU plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Default | Parameter | Description |
|--|--|--|--|--|
| agent_param_plugins_nvidia_system_path | `string` | /usr/libexec/zabbix/zabbix-agent2-plugin-nvidia-gpu | [**Plugins.NVIDIA.System.Path**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/nvidia_gpu) | Path to the NVIDIA GPU plugin executable.
| agent_param_plugins_nvidia_timeout | `int` || [**Plugins.NVIDIA.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/nvidia_gpu) | Specifies the maximum time (in seconds) to wait for a server response during connection attempts and subsequent operations in the session. The global item-type timeout or individual item timeout will override this value if greater.
### Zabbix **agent 2 Redis plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_redis_keepalive | `int` | [**Plugins.Redis.KeepAlive**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/redis_plugin) | Maximum time of waiting (in seconds) before unused plugin connections are closed.
| agent_param_plugins_redis_timeout | `int` | [**Plugins.Redis.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/redis_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
| agent_param_plugins_redis_sessions | `list of dictionaries` | [**Plugins.Redis.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/redis_plugin) | Holds the list of connection credentials in dictionary form with the keys: `{ name: "", uri: "", password: "" }`
| agent_param_plugins_redis_default | `dictionary` | [**Plugins.Redis.Sessions**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/redis_plugin) | Holds the default connection credentials in dictionary form with the keys: `{ uri: "", password: "" }`
### Zabbix **agent 2 Smart plugin** parameters:
For these settings to take effect, the plugin should be listed in [`agent_2_plugin_list`](#general-settings).
| Variable | Type | Parameter | Description |
|--|--|--|--|
| agent_param_plugins_smart_path | `string` | [**Plugins.Smart.Path**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/smart_plugin) | Path to the smartctl executable.
| agent_param_plugins_smart_timeout | `int` | [**Plugins.Smart.Timeout**](https://www.zabbix.com/documentation/current/en/manual/appendix/config/zabbix_agent2_plugins/smart_plugin) | Request execution timeout (how long to wait for a request to complete before shutting it down).
Hints & Tags
-----
- Wrong variable definition level can be punishing for starters. Begin with [**variable precedence learning**](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable).
We recommend [**organizing host and group variables**](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#organizing-host-and-group-variables) on inventory level. It is handy for big environments and will fit most use cases.
- Zabbix agent role uses **handlers** to reload systemd daemon and restart `zabbix-agent[2]` service.
To trigger **handler** execution each time (not only after changes made), compliment your run with `restart` tag. Add it after `all` tag or other tasks (those not marked with `restart` tag will be skipped).
ansible-playbook -i inventory play.yml -t all,restart
- To stop and remove `zabbix-agent[2]` service, use `remove` tag. This will clear custom overrides if present and uninstall packages, according to variables defined.
ansible-playbook -i inventory play.yml -t remove
- If `agent_param_userparameter` is modified and registered as the only change during role run, it will trigger Zabbix agent[2] runtime command to reload user parameters without agent restart.
- To run only tasks that modify user parameters, pass `userparam` tag. Task sequence will be limited to:
- Copying include folder.
- Copying script folder.
- Adding a list of user parameters from `agent_param_userparameter` variable to configuration file.
- Executing runtime command to reload user parameters.
ansible-playbook -i inventory play.yml -t userparam
Playbook examples
-----------------
- ### Playbook 1:
**Latest LTS Zabbix agentd deployment for active checks only.**
1. Here we will deploy Zabbix agentd (from defaults: `agent_variant = 1`).
2. Major version defaults to current LTS version.
3. Since we are removing passive checks with `agent_param_startagents = 0`, firewalld rule application will be skipped.
4. Hostname of the agent or `agent_param_hostname` defaults to the inventory hostname.
5. We can prepare metadata for active agent autoregistration by using Ansible special variables and filters.
In this example we will use groups from the inventory to form the metadata. Special variable `group_names` contains the list of groups assigned to the host. Let's concatenate this list to the string separated by commas. It will look as follows: "DB,Linux,MySQL,etc"
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_startagents: 0 # do not spawn passive check processes that listen for connections;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
```
- ### Playbook 2:
**6.4 version of Zabbix agent 2 for both passive and active checks + Iptables.**
1. To deploy Zabbix agent 2, define `agent_variant = 2`.
2. You can specify Zabbix agent major version manually: `agent_major_version: "6.4"`.
3. Same metadata as described in the [first example](#playbook-1).
4. Disable application of the firewall rule using firewalld daemon: `agent_apply_firewalld_rule: false`.
5. Enable firewall rule application using iptables module. **Note** that modern Ubuntu distributions use nftables, and iptables are DEPRECATED.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_variant: 2
agent_major_version: 6.4
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
agent_apply_firewalld_rule: false # "auto" is the default and recommended value;
agent_apply_iptables_rule: true # "auto" is the default value;
agent_firewall_allow_from: 127.0.0.1 # limit listening on agent port only from the defined source address
```
- ### Playbook 3:
**Zabbix agentd for both passive and active checks with PSK encryption for autoregistration.**
1. Same metadata for autoregistration as described in the [first example](#playbook-1).
2. Set incoming and outgoing connection to be encrypted with `psk`
- `agent_param_tlsconnect` is a single-type setting, so string input is expected;
- `agent_param_tlsaccept` can simultaneously work with all 3 types, so we are using list format here;
- `agent_source_tlspskfile` can use relative or absolute path to an existent key or a place where it should be generated. Because of autoregistration, single PSK key should be used and identity for all agents should be registered. After the key is generated, add it to Zabbix using GUI (Administration > General > Autoregistration);
- `agent_param_tlspskidentity` is used for passing the identity name to be placed in Zabbix agent configuration file. The same should be placed in Zabbix autoregistration options (Administration > General > Autoregistration).
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
agent_param_tlsconnect: psk
agent_param_tlsaccept: [psk]
agent_source_tlspskfile: TEST/autoregistration.psk # "autoregistration" key will be placed to TEST folder;
agent_param_tlspskidentity: 'PSK_ID_AUTOREGISTRATION' # length <= 128 char
```
- ### Playbook 4:
**Zabbix agentd with certificate-secured connections.**
1. When passive checks are enabled, the role attempts to apply **firewalld** rule to allow listening on Zabbix agent port (which defaults to `agent_param_listenport = 10050`). Firewalld should be installed on the target machine or this step will be skipped.
2. Same metadata as described in the [first example](#playbook-1).
3. When `cert` is specified in `agent_param_tlsconnect` or `agent_param_tlsaccept` source, the path to certificate files becomes mandatory. Check the configuration example below. We are pointing to "certs/" folder which holds the certificate files named according to the host inventory name.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
agent_param_tlsconnect: cert # restrict active checks to certificate only;
agent_param_tlsaccept: ["cert", "unencrypted"] # allow encrypted and unencrypted passive checks;
agent_source_tlscafile: certs/ca.crt # provide the path to CA certificate file on Ansible execution environment;
# agent_source_tlscrlfile: # certificate revocation list, can be omitted;
agent_source_tlscertfile: certs/{{ inventory_hostname }}.crt # Zabbix agent certificate path on the execution environment;
agent_source_tlskeyfile: certs/{{ inventory_hostname }}.key # key file path on the execution environment;
agent_param_tlsservercertissuer: CN=root-ca # certificate issuer restriction (optional);
agent_param_tlsservercertsubject: CN=server # certificate subject restriction (optional);
```
- ### Playbook 5:
**6.4 version of Zabbix agent 2 for MongoDB monitoring.**
1. To deploy Zabbix agent 2, define `agent_variant = 2`.
2. You can specify Zabbix agent major version manually: `agent_major_version: "6.4"`.
3. Same metadata as described in the [first example](#playbook-1).
4. When passive checks are enabled, the role attempts to apply **firewalld** rule to allow listening on Zabbix agent port (which defaults to `agent_param_listenport = 10050`). Firewalld should be installed on the target machine or this step will be skipped.
5. Since Zabbix 6.4, loadable plugins are not installed by `zabbix-agent2` package as dependency. We need to add it to `agent_2_plugin_list`.
6. We will configure a TLS connection session within MongoDB, using the same approach with source files. The role will transfer them to the target machine and configure automatically. The certificate files will be placed to Zabbix agent service user home folder.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_variant: 2
agent_major_version: 6.4
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
agent_2_plugin_list: [ceph, docker, memcached, modbus, mqtt, mysql, oracle, redis, smart, mongodb]
agent_param_plugins_mongodb_sessions:
- name: "sessionname"
uri: "someuri"
user: "someuser"
password: "somepassword"
tlsconnect: "required"
## Location of the source certificate files on Ansible execution environment.
source_tlscafile: "certs/ca.crt"
source_tlscertfile: "certs/{{ inventory_hostname }}.crt"
source_tlskeyfile: "certs/{{ inventory_hostname }}.key"
```
- ### Playbook 6:
**Zabbix agentd downgrade from 6.4 to 6.0**
1. You can specify Zabbix agent major version manually: `agent_major_version: "6.0"`.
2. The attempt to install earlier version will fail because the newer one is already installed. To overcome this, previous packages should be removed first.
3. Same metadata as described in the [first example](#playbook-1).
4. When passive checks are enabled, the role attempts to apply **firewalld** rule to allow listening on Zabbix agent port (which defaults to `agent_param_listenport = 10050`). Firewalld should be installed on the target machine or this step will be skipped.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_major_version: "6.0"
agent_remove_previous_packages: true # removes previously installed package of Zabbix agent (according to current settings);
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
- ### Playbook 7:
**Zabbix agentd running under custom user**
1. Same metadata as described in the [first example](#playbook-1).
2. When passive checks are enabled, the role attempts to apply **firewalld** rule to allow listening on Zabbix agent port (which defaults to `agent_param_listenport = 10050`). Firewalld should be installed on the target machine or this step will be skipped.
3. Setting `agent_service_user` will trigger custom user task list. It will create user, user group, home folder, systemd overrides and a separate log folder.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
agent_service_user: dor # if agent_service_user is not "zabbix", multiple changes are applied
agent_service_group: blue
agent_service_uid: 1115
agent_service_gid: 1115
```
- ### Playbook 8:
**Update Zabbix agentd to latest minor version**
1. Same metadata as described in the [first example](#playbook-1).
2. When passive checks are enabled, the role attempts to apply **firewalld** rule to allow listening on Zabbix agent port (which defaults to `agent_param_listenport = 10050`). Firewalld should be installed on the target machine or this step will be skipped.
3. Setting `agent_package_state = latest` will install the latest minor version of the packages.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
agent_package_state: latest # use latest available minor version
```
- ### Playbook 9:
**Deploy Zabbix agent without direct internet access from target machine, by using HTTP proxy.**
1. Same metadata as described in the [first example](#playbook-1).
2. When passive checks are enabled, the role attempts to apply **firewalld** rule to allow listening on Zabbix agent port (which defaults to `agent_param_listenport = 10050`). Firewalld should be installed on the target machine or this step will be skipped.
3. Supply HTTP proxy address to the `agent_http_proxy` variable.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
agent_param_server: 127.0.0.1 # address of Zabbix server to accept connections from;
agent_param_serveractive: 127.0.0.1 # address of Zabbix server to connect using active checks;
agent_param_hostmetadata: '{{ group_names | join(",") }}' # concatenate group list to the string;
agent_http_proxy: http://host.containers.internal:8123 # HTTP proxy address.
```
- ### Playbook 10:
**Deploy Zabbix agent with passive checks only and add hosts to Zabbix.**
1. Fill Zabbix agent configuration. Here we will allow Zabbix server to communicate with agent and apply firewall rule to accept connection only from Zabbix server.
2. Active agent autoregistration does not work with passive checks. So we need to use Zabbix API to add new host with passive checks only. Add [**zabbix.zabbix.host**](https://github.com/zabbix/ansible-collection/blob/main/roles/host/README.md) role to the same Ansible `play` to inherit variables from the first role.
3. Fill Zabbix API connection properties.
4. Fill Zabbix host configuration. This time, we will add only template to assign. Default configuration will apply host name and agent connection properties from Ansible inventory.
```yaml
- hosts: all
roles:
- role: zabbix.zabbix.agent
### Zabbix agent configuration
agent_param_server: 256.256.256.256 # address of Zabbix server to accept connections from monitoring instance;
agent_firewall_allow_from: 256.256.256.256 # address of Zabbix server to allow connections from monitoring instance using firewalld;
- role: zabbix.zabbix.host
### Zabbix API properties
host_zabbix_api_server: zabbix.frontend.loc # Zabbix frontend server;
host_zabbix_api_port: 443 # Zabbix fronted connection port;
host_zabbix_api_user: Admin # Zabbix user name for API connection;
host_zabbix_api_password: zabbix # Zabbix user password for API connection;
host_zabbix_api_use_ssl: True # Use secure connection;
### Zabbix host configuration
host_templates: ["Linux by Zabbix agent"] # Assign list of templates to the host;
```
License
-------
Ansible Zabbix collection is released under the GNU Affero General Public License (AGPL) version 3. The formal terms of the GPL can be found at http://www.fsf.org/licenses/.