--- - name: "DEBUG : Base info" ansible.builtin.debug: msg: > variant: {{ agent_variant | string }} distr: {{ ansible_distribution }} major: {{ ansible_distribution_major_version }} become_method: {{ ansible_become_method | default(None) }} agent_logrotate_path: {{ agent_logrotate_path | default(None) }} agent_param_include: {{ agent_param_include | default(None) }} tags: [never, debug] - name: "Assert : Variables validation" ansible.builtin.assert: that: - agent_package_state in ["present", "latest"] quiet: true tags: [assert, deploy, config] # - name: Assert TLS files or settings # when: >- # agent_param_tlsconnect == "cert" or "cert" in agent_param_tlsaccept # ansible.builtin.assert: # that: # - agent_source_tlscertfile is defined and agent_source_tlscertfile # or agent_param_tlscertfile is defined and agent_param_tlscertfile # - agent_source_tlskeyfile is defined and agent_source_tlskeyfile # or agent_param_tlskeyfile is defined and agent_param_tlskeyfile # - agent_source_tlscafile is defined and agent_source_tlscafile # or agent_param_tlscafile is defined and agent_param_tlscafile # quiet: true # tags: [assert, deploy, config] - name: "Variables : Include system and distribution specific" ansible.builtin.include_vars: "{{ var_item }}.yml" loop: "{{ agent_internal_var_list | select }}" loop_control: loop_var: var_item vars: agent_internal_var_list: # - '{{ ansible_system | lower }}' - "{{ ansible_os_family | lower }}" # - '{{ "debian" if ansible_distribution in ["Debian", "Ubuntu"] else None }}' # - '{{ "redhat" if ansible_distribution in ["RedHat", "AlmaLinux", "Rocky", "CentOS", "OracleLinux", "Amazon", "Fedora"] else None }}' tags: [vars, verify, remove, deploy, config] - name: "Variables : Custom user : Overrides" when: >- agent_service_user is defined and agent_service_user and agent_service_user != "zabbix" # and agent_service_group != "zabbix" ## variable change required for custom user ansible.builtin.include_vars: custom_user_overrides.yml tags: [vars, verify, remove, deploy, config] - name: "Variables: Get/Generate PSK keys" # or zabbix_host_tls_connect == "psk" or "psk" in zabbix_host_tls_accept) when: >- (agent_param_tlsconnect == "psk" or "psk" in agent_param_tlsaccept) and (agent_tls_psk_value is not defined or not agent_tls_psk_value) ansible.builtin.set_fact: # value of hexadecimal within range 32 to 128 chars | choosing 128 # password lookup module generates upper and lower case symbols, which is lowered by filter. local temporary files will be left unmodified agent_tls_psk_value: '{{ lookup("password", agent_source_tlspskfile + " chars=hexdigits length=128") | lower }}' tags: [vars, verify, deploy, config] - name: "Variables: TLS Certificate parameters" when: >- (agent_param_tlsconnect == "cert" or "cert" in agent_param_tlsaccept) and (agent_source_tlscertfile is defined and agent_source_tlskeyfile is defined and agent_source_tlscafile is defined) ansible.builtin.include_vars: tls_cert_parameters.yml tags: [vars, verify, deploy, config] - name: "Variables: Agent2 plugin settings" when: agent_variant | string == '2' ansible.builtin.include_tasks: agent2_plugin_settings.yml tags: [vars, verify, remove, deploy, config] - name: "DEBUG : Package info" ansible.builtin.debug: msg: "list: {{ agent_package_list }}" tags: [never, debug] - name: "DEBUG : Zabbix agent variant" ansible.builtin.debug: msg: 'Variant: {{ agent_variant | string }} | groups: {{ group_names | join(", ") }}' tags: [never, debug] - name: Include package clearing tasks when: >- agent_remove_previous_packages is defined and agent_remove_previous_packages or "remove" in ansible_run_tags ansible.builtin.include_tasks: remove_packages_{{ ansible_system | lower }}.yml tags: [remove, deploy] - name: Include OS packager(yum/apt) specific tasks ansible.builtin.include_tasks: "{{ ansible_os_family | lower }}.yml" # remove custom user overrides if left from previous deployment - name: Include custom user cleaning tasks when: > agent_service_user is not defined or not agent_service_user or agent_service_user == "zabbix" ansible.builtin.include_tasks: custom_user_clean_{{ ansible_system | lower }}.yml tags: [deploy] - name: Include custom user tasks when: > agent_service_user is defined and agent_service_user and agent_service_user != "zabbix" ansible.builtin.include_tasks: custom_user_{{ ansible_system | lower }}.yml tags: [deploy] - name: Firewall task list include ansible.builtin.include_tasks: "{{ firewall_task_item }}.yml" loop: "{{ agent_internal_task_list | select }}" loop_control: loop_var: firewall_task_item vars: agent_internal_task_list: - '{{ "firewalld" if (agent_apply_firewalld_rule is defined and agent_apply_firewalld_rule in ["force", "auto"]) else None }}' - '{{ "iptables" if (agent_apply_iptables_rule is defined and agent_apply_iptables_rule) else None }}' tags: [firewall, deploy] # changing only main conf file. Free to use customization in includes(unless no includes specified or include path changed) - name: Configuration file maintenance when: agent_package_state != 'absent' become: true notify: Service restart ansible.builtin.template: backup: true src: zabbix_agent{{ agent_variant | string }}_{{ agent_major_version | string }}.conf.j2 dest: "{{ agent_conf_file.path }}" mode: "{{ agent_conf_file.permissions.mode }}" owner: "{{ agent_conf_file.permissions.user }}" group: "{{ agent_conf_file.permissions.group }}" tags: [deploy, config] - name: "Upload : Included configuration dir (to the 1st include path)" when: agent_source_conf_dir is defined and agent_source_conf_dir become: true notify: - Service restart - Reload user parameters # ansible.posix.synchronize: ansible.builtin.copy: src: "{{ agent_source_conf_dir }}/" dest: "{{ agent_param_include[0] | dirname }}" mode: "{{ agent_conf_file.permissions.mode }}" directory_mode: "{{ agent_conf_file.folder_permissions.mode }}" owner: "{{ agent_conf_file.permissions.user }}" group: "{{ agent_conf_file.permissions.group }}" # recursive: true # delete: true tags: [userparam, deploy, config, upload] - name: Zabbix agent configuration "Include folders" maintenance # create path & apply permissions become: true notify: Service restart ansible.builtin.file: path: "{{ item | dirname }}" state: directory mode: "{{ agent_conf_file.folder_permissions.mode }}" owner: "{{ agent_conf_file.folder_permissions.user }}" group: "{{ agent_conf_file.folder_permissions.group }}" # recurse: true loop: '{{ agent_param_include + agent_param_includeplugins | select | list if agent_variant | string == "2" else agent_param_include }}' tags: [deploy, config] - name: "Zabbix agent2 plugin configuration maintenance : Deploy configuration files" when: agent_package_state != 'absent' and agent_variant | string == '2' become: true notify: Service restart ansible.builtin.template: backup: false src: a2_plugin_{{ plugin_name_item }}.conf.j2 dest: "{{ agent_param_includeplugins[0] | dirname }}/{{ plugin_name_item }}.conf" mode: "{{ agent_conf_file.permissions.mode }}" owner: "{{ agent_conf_file.permissions.user }}" group: "{{ agent_conf_file.permissions.group }}" loop_control: loop_var: plugin_name_item loop: "{{ agent_2_plugin_list | select | list }}" tags: [deploy, config] - name: "Zabbix agent2 plugin configuration maintenance : Clear previous excess plugin configuration files" # remove plugin configuration files from previous installation if needed when: agent_package_state != 'absent' and agent_variant | string == '2' become: true notify: Service restart ansible.builtin.file: path: "{{ agent_param_includeplugins[0] | dirname }}/{{ excess_plugin_name_item }}.conf" state: absent ### MAYBE FORCE defaults instead of current settings??? mode: "{{ agentd_conf_file_stat.stat.mode | default(agent_conf_file.permissions.mode) }}" owner: "{{ agentd_conf_file_stat.stat.pw_name | default(agent_conf_file.permissions.user) }}" group: "{{ agentd_conf_file_stat.stat.gr_name | default(agent_conf_file.permissions.group) }}" loop_control: loop_var: excess_plugin_name_item # loop over a list of plugins not used in current setup loop: "{{ agent_2_full_plugin_list | difference(agent_2_plugin_list) }}" tags: [deploy, config] - name: 'Upload : "scripts" folder' when: agent_source_scripts_dir is defined and agent_source_scripts_dir become: true # ansible.posix.synchronize: ansible.builtin.copy: src: "{{ agent_source_scripts_dir }}/" dest: "{{ agent_service_user_home }}/{{ agent_binary_name | upper }}/scripts/" mode: u=rwx,g=rx,o=r directory_mode: u=rwx,g=rx,o=rx owner: "{{ agent_service_user }}" group: "{{ agent_service_group }}" # recursive: true ## Default zabbix user home folder /var/lib/zabbix can hold other component data... keeping all for now # delete: false tags: [userparam, deploy, config, upload] - name: 'Upload : "modules" folder' when: agent_source_modules_dir is defined and agent_source_modules_dir and agent_variant | string != '2' become: true notify: Service restart # ansible.posix.synchronize: ansible.builtin.copy: src: "{{ agent_source_modules_dir }}/" dest: "{{ agent_param_loadmodulepath }}/" mode: u=rwx,g=rx,o=r directory_mode: u=rwx,g=rx,o=rx owner: "{{ agent_service_user }}" group: "{{ agent_service_group }}" # recursive: true ## Default zabbix user home folder /var/lib/zabbix can hold other component data... keeping all for now # delete: false tags: [deploy, upload] # Add userparams to first include folder - name: Fill configuration with custom UserParameters become: true notify: - Reload user parameters ansible.builtin.template: backup: false src: zabbix_agent.{{ item }}.j2 dest: "{{ agent_param_include[0] | dirname }}/{{ item }}" mode: "{{ agent_conf_file.permissions.mode }}" owner: "{{ agent_conf_file.permissions.user }}" group: "{{ agent_conf_file.permissions.group }}" loop: "{{ agent_internal_template_list | select }}" vars: agent_internal_template_list: - userparameters.conf tags: [userparam, deploy, config] # Add aliases to first include folder - name: Fill configuration with custom Aliases become: true notify: - Service restart ansible.builtin.template: backup: false src: zabbix_agent.{{ item }}.j2 dest: "{{ agent_param_include[0] | dirname }}/{{ item }}" mode: "{{ agent_conf_file.permissions.mode }}" owner: "{{ agent_conf_file.permissions.user }}" group: "{{ agent_conf_file.permissions.group }}" loop: "{{ agent_internal_template_list | select }}" vars: agent_internal_template_list: - aliases.conf tags: [deploy, config] # Creates TLS folder path and applies permissions - name: "Folder maintenance : TLS folders" when: agent_package_state != 'absent' become: true ansible.builtin.file: path: '{{ agent_service_user_home + "/" + folder_item }}' state: directory mode: u=rwx,g=,o= owner: "{{ agent_service_user }}" group: "{{ agent_service_group }}" loop_control: loop_var: folder_item loop: "{{ agent_internal_maintenance_folders | select | list }}" vars: agent_internal_maintenance_folders: - '{{ agent_binary_name | upper + "/.CERT/" if agent_source_tlscafile is defined else None }}' - '{{ agent_binary_name | upper + "/.PSK/" if "psk" in agent_param_tlsaccept or agent_param_tlsconnect == "psk" else None }}' - '{{ agent_binary_name | upper + "/.CERT/MYSQL/DEFAULT" if agent_variant | string == "2" else None }}' - '{{ agent_binary_name | upper + "/.CERT/POSTGRESQL/DEFAULT" if agent_variant | string == "2" else None }}' - '{{ agent_binary_name | upper + "/.CERT/MONGODB/DEFAULT" if agent_variant | string == "2" else None }}' - '{{ agent_binary_name | upper + "/.CERT/MQTT/DEFAULT" if agent_variant | string == "2" else None }}' - '{{ agent_binary_name | upper + "/.CERT/MSSQL/DEFAULT" if agent_variant | string == "2" else None }}' tags: [deploy, config] ## Consider removing agent_source_* file checks. To report problem on this step instead of waiting for agent restart handler!!! ## use assert instead - name: "Upload : TLS Certificates" when: >- (agent_param_tlsconnect == "cert" or "cert" in agent_param_tlsaccept) and (agent_source_tlscertfile is defined and agent_source_tlskeyfile is defined and agent_source_tlscafile is defined) become: true notify: Service restart ansible.builtin.copy: src: "{{ tls_file_item.source }}" dest: "{{ tls_file_item.target }}" mode: u=rwx,g=,o= directory_mode: u=rwx,g=,o= owner: "{{ agent_service_user }}" group: "{{ agent_service_group }}" # recursive: true loop_control: loop_var: tls_file_item loop: "{{ agent_internal_tls_file_list | select }}" vars: agent_internal_tls_file_list: - { source: "{{ agent_source_tlscafile }}", target: "{{ agent_param_tlscafile }}" } - '{{ {"source": agent_source_tlscrlfile, "target": agent_param_tlscrlfile} if agent_source_tlscrlfile is defined else None }}' - { source: "{{ agent_source_tlscertfile }}", target: "{{ agent_param_tlscertfile }}" } - { source: "{{ agent_source_tlskeyfile }}", target: "{{ agent_param_tlskeyfile }}" } tags: [deploy, config, upload] - name: Placing PSK key file when: agent_package_state != 'absent' and (agent_param_tlsconnect == "psk" or "psk" in agent_param_tlsaccept ) become: true notify: Service restart ansible.builtin.template: backup: false src: psk_value.j2 dest: "{{ agent_param_tlspskfile }}" mode: u=rw,g=,o= owner: "{{ agent_service_user }}" group: "{{ agent_service_group }}" tags: [deploy, config] - name: "Upload : Zabbix agent2 : TLS certificates for plugins" when: >- agent_variant | string == '2' and plugin_tls_file_item.source is defined and plugin_tls_file_item.source become: true notify: Service restart ansible.builtin.copy: src: "{{ plugin_tls_file_item.source }}" dest: "{{ plugin_tls_file_item.target }}" mode: u=rwx,g=,o= directory_mode: u=rwx,g=,o= owner: "{{ agent_service_user }}" group: "{{ agent_service_group }}" # recursive: true loop_control: loop_var: plugin_tls_file_item label: "{{ plugin_tls_file_item.source | default(None), plugin_tls_file_item.target }}" loop: "{{ agent_internal_plugins_mysql_tls_file_list | default([]) + agent_internal_plugins_postgresql_tls_file_list | default([]) + agent_internal_plugins_mongodb_tls_file_list | default([]) + agent_internal_plugins_mqtt_tls_file_list | default([]) + agent_internal_plugins_mssql_tls_file_list | default([]) + agent_internal_plugins_mysql_default_tls_file_list | default([]) + agent_internal_plugins_postgresql_default_tls_file_list | default([]) + agent_internal_plugins_mqtt_default_tls_file_list | default([]) + agent_internal_plugins_mssql_default_tls_file_list | default([]) }}" tags: [deploy, config, upload] - name: Logrotate file maintenance become: true ansible.builtin.template: backup: false src: zabbix_agent.logrotate.j2 dest: "{{ agent_logrotate_path }}" # !!! Add defaults for logrotate conf file mode: "{{ agent_conf_file.permissions.mode }}" owner: "{{ agent_conf_file.permissions.user }}" group: "{{ agent_conf_file.permissions.group }}" tags: [deploy] ### including SE tasks when ansible_facts testifies that SELinux is enabled - name: "Include : Selinux tasks" when: ansible_selinux.status is defined and ansible_selinux.status == "enabled" ansible.builtin.include_tasks: selinux.yml tags: [selinux, deploy] - name: "Systemctl : Service enabled" become: true when: agent_package_state != 'absent' ansible.builtin.systemd: name: "{{ agent_service_name }}" enabled: true tags: [deploy] - name: Forcing service restart ansible.builtin.debug: msg: Forced changed_when: true notify: - Reload systemd daemon - Service restart tags: [never, restart] - name: Forcing userparameter reload ansible.builtin.debug: msg: Forced changed_when: true notify: - Reload user parameters tags: [never, userparam] - name: Flush handlers ansible.builtin.meta: flush_handlers # trigger handler execution now (if notified) tags: [restart, deploy, config] # consider running check in default run # - name: 'Service started' # become: true # when: agent_package_state != 'absent' # ansible.builtin.systemd: # name: '{{ agent_service_name }}' # state: started - name: "Include : verify steps" ansible.builtin.include_tasks: verify.yml when: >- "remove" not in ansible_run_tags tags: [never, verify]