From 0830507cf78393ac29763fee4a2f8f290c42c1b4 Mon Sep 17 00:00:00 2001 From: Simon Cornet Date: Wed, 16 Apr 2025 17:32:51 +0200 Subject: [PATCH] feat: initial commit --- .ansible-lint | 22 +++++++++ .gitignore | 1 + .gitlab-ci.yml | 16 ++++++ .gitlab/deployment.yaml | 31 ++++++++++++ .gitlab/linting.yaml | 17 +++++++ .yamllint | 30 +++++++++++ README.md | 56 +++++++++++++++++++++ defaults/main.yaml | 10 ++++ handlers/main.yaml | 8 +++ meta/main.yaml | 25 ++++++++++ renovate.json | 7 +++ tasks/config.yaml | 21 ++++++++ tasks/install.yaml | 71 +++++++++++++++++++++++++++ tasks/main.yaml | 34 +++++++++++++ tasks/prerequisites.yaml | 61 +++++++++++++++++++++++ templates/sudoers.d/zabbix.j2 | 1 + templates/zabbix/zabbix_agent.conf.j2 | 25 ++++++++++ templates/zabbix/zabbix_agent.psk.j2 | 1 + vars/Debian.yaml | 15 ++++++ vars/Suse.yaml | 7 +++ 20 files changed, 459 insertions(+) create mode 100644 .ansible-lint create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .gitlab/deployment.yaml create mode 100644 .gitlab/linting.yaml create mode 100644 .yamllint create mode 100644 README.md create mode 100644 defaults/main.yaml create mode 100644 handlers/main.yaml create mode 100644 meta/main.yaml create mode 100644 renovate.json create mode 100644 tasks/config.yaml create mode 100644 tasks/install.yaml create mode 100644 tasks/main.yaml create mode 100644 tasks/prerequisites.yaml create mode 100644 templates/sudoers.d/zabbix.j2 create mode 100644 templates/zabbix/zabbix_agent.conf.j2 create mode 100644 templates/zabbix/zabbix_agent.psk.j2 create mode 100644 vars/Debian.yaml create mode 100644 vars/Suse.yaml diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..5397fc0 --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,22 @@ +--- + +exclude_paths: + - ".gitlab/*" + - ".gitlab-ci.yml" + - "meta/main.yaml" + - "vars/*" + +kinds: + - playbook: "**/*.{yml,yaml}" + +skip_list: + - "command-shell" + - "experimental" + - "git-latest" + - "no-changed-when" + - "no-handler" + - "name[casing]" + - "name[template]" + - "risky-file-permissions" + - "schema[playbook]" + - "var-naming[no-role-prefix]" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..904cae8 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.ansible diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..5d82fc7 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,16 @@ +--- + +# gitLab ci stages +stages: + + # deployment + - "linting" + - "deployment" + + +# include jobs +include: + + # deployment + - local: ".gitlab/linting.yaml" + - local: ".gitlab/deployment.yaml" diff --git a/.gitlab/deployment.yaml b/.gitlab/deployment.yaml new file mode 100644 index 0000000..040754b --- /dev/null +++ b/.gitlab/deployment.yaml @@ -0,0 +1,31 @@ +--- +# deploy ansible/roles/common code +deployment: + stage: "deployment" + image: + name: "cr.simoncor.net/siempie/ssh-client:latest" + entrypoint: ["/bin/sh", "-c"] + rules: + + # run only on push to default branch + - if: + '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == + $CI_DEFAULT_BRANCH' + - when: "never" + + # prepare ssh + before_script: + # prepare ssh + - | + # prepare ssh + mkdir -p ~/.ssh + chmod 700 ~/.ssh + echo "$SSH_CONFIG" > ~/.ssh/config + echo "$SSH_DEPLOYMENT_KEY" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + + # deployment commands + script: + - | + # install ansible roles dependancies + ssh $SSH_DEPLOYMENT_USER@$ANSIBLE_SERVER "sudo /usr/local/bin/ansible-galaxy install -r /etc/ansible/roles/requirements.yaml --force" diff --git a/.gitlab/linting.yaml b/.gitlab/linting.yaml new file mode 100644 index 0000000..01b8aa3 --- /dev/null +++ b/.gitlab/linting.yaml @@ -0,0 +1,17 @@ +--- + +# linting +linting: + stage: "linting" + image: + name: "cr.simoncor.net/siempie/ansible-deployment:latest" + entrypoint: ["/bin/sh", "-c"] + rules: + + # run only on push to default branch + - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' + - when: "never" + + # start linting + script: + - "ansible-lint -c .ansible-lint ." diff --git a/.yamllint b/.yamllint new file mode 100644 index 0000000..e4db48c --- /dev/null +++ b/.yamllint @@ -0,0 +1,30 @@ +--- +extends: 'default' + +rules: + braces: + max-spaces-inside: 1 + forbid: true + comments: + min-spaces-from-content: 1 + comments-indentation: false + empty-lines: + max: 2 + indentation: + spaces: 2 + check-multi-line-strings: true + line-length: + max: 130 + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + new-line-at-end-of-file: 'enable' + octal-values: + forbid-implicit-octal: true + forbid-explicit-octal: true + truthy: + allowed-values: + - 'true' + - 'false' + quoted-strings: + quote-type: 'any' + required: true diff --git a/README.md b/README.md new file mode 100644 index 0000000..5829fcc --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# Overview +This role the installation and configuration of the Zabbix Agent version 2. + +# Supported Operating Systems +| Operating System | Version | +| --- | ----- | +| Debian | 12 | +| SLES | 15 | +| Ubuntu | 22.04 LTS | +| Ubuntu | 24.04 LTS | + +# Variables +| Variable | Type | Default | Required | +| --- | --- | --- | --- | +| zabbix_proxy_address | string | | Yes | +| zabbix_agent_hostinterface | string | inventory_hostname | No | +| zabbix_agent_hostname | string | inventory_hostname | No | +| zabbix_agent_psk_enable | bool | true | No | +| zabbix_agent_psk_id | string | | Yes | +| zabbix_agent_psk | string(enc) | | Yes | +| zabbix_user_sudo | bool | true | No | + +# Example usage +With PSK: +``` +zabbix_proxy_address: "proxy.monitor.localnet.internal" +zabbix_agent_psk_id: "client-psk" +zabbix_agent_psk: !vault + $ANSIBLE_VAULT;1.1;AES256 + 31633463613336373164373333633038393164383835646633303163316665303934646363383530 + ... +``` +Without PSK: +``` +zabbix_proxy_address: "proxy.monitor.localnet.internal" +``` + +## DNS override +If DNS is complicated or permanently broken for some reason. We can override the +hostname and hostinterface. +The hostname is the visible name in Zabbix. +The hostinterface is what Zabbix uses to connect to the host. +``` +zabbix_agent_hostname: "server.example.com" +zabbix_agent_hostinterface: "192.168.10.10" +``` +This is possible, but please `only use if really required`. + +# Tags +| Tags | Purpose | +| --- | --- | +| zabbix_agent | Executes the whole playbook | +| zabbix_agent_config | Only manage Zabbix Agent 2 configuration | +| zabbix_agent_install | Only manage Zabbix Agent 2 installation | +| zabbix_agent_prereq | Only manage Zabbix Agent 2 prerequisites | + diff --git a/defaults/main.yaml b/defaults/main.yaml new file mode 100644 index 0000000..75a6f9b --- /dev/null +++ b/defaults/main.yaml @@ -0,0 +1,10 @@ +--- + +# zabbix_version +zabbix_major_version: "7.2" + +# zabbix agent defaults +zabbix_agent_psk_enable: true + +# zabbix user permissions +zabbix_user_sudo: true diff --git a/handlers/main.yaml b/handlers/main.yaml new file mode 100644 index 0000000..6f107cb --- /dev/null +++ b/handlers/main.yaml @@ -0,0 +1,8 @@ +--- + +# zabbix agent +- name: "restart zabbix-agent" + ansible.builtin.service: + name: "zabbix-agent2" + enabled: true + state: "restarted" diff --git a/meta/main.yaml b/meta/main.yaml new file mode 100644 index 0000000..816c6cf --- /dev/null +++ b/meta/main.yaml @@ -0,0 +1,25 @@ +--- +galaxy_info: + role_name: "zabbix_agent" + author: "Nobody" + description: "Installs and configures the Zabbix Agent(2)" + namespace: "sharedcloudservices" + company: "Shared Cloud Services" + license: "SCS" + min_ansible_version: "2.16" + platforms: + - name: "Debian" + versions: + - "bookworm" + + - name: "SLES" + versions: + - "15" + + - name: "Ubuntu" + versions: + - "jammy" + - "noble" + +dependencies: + - "community.general" diff --git a/renovate.json b/renovate.json new file mode 100644 index 0000000..da8f5e1 --- /dev/null +++ b/renovate.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ "local>cicd/renovate" ], + "ansible": { + "fileMatch": [ "(.*).ya?ml$" ] + } +} diff --git a/tasks/config.yaml b/tasks/config.yaml new file mode 100644 index 0000000..983480e --- /dev/null +++ b/tasks/config.yaml @@ -0,0 +1,21 @@ +--- + +# setup psk +- name: "setup psk" + ansible.builtin.template: + src: "templates/zabbix/agent/zabbix_agent.psk.j2" + dest: "/etc/zabbix/zabbix_agent.psk" + owner: "zabbix" + group: "zabbix" + mode: "0640" + notify: "restart zabbix-agent" + +# config agent +- name: "config agent" + ansible.builtin.template: + src: "templates/zabbix/agent/zabbix_agent.conf.j2" + dest: "/etc/zabbix/zabbix_agent2.conf" + owner: "root" + group: "root" + mode: "0664" + notify: "restart zabbix-agent" diff --git a/tasks/install.yaml b/tasks/install.yaml new file mode 100644 index 0000000..cf119f5 --- /dev/null +++ b/tasks/install.yaml @@ -0,0 +1,71 @@ +--- + +# find current zabbix version +- name: "check for old zabbix-release" + ansible.builtin.shell: + cmd: "zabbix_agent2 --version | head -n 1" + changed_when: false + failed_when: false + ignore_errors: true + register: "zabbix_current_version" + +# install zabbix-agent2 +- name: "install zabbix-agent2" + when: "zabbix_major_version not in zabbix_current_version.stdout" + block: + + # install repository - debian + - name: "install repository" + when: 'ansible_os_family == "Debian"' + block: + + # remove old agent + - name: "remove old agent" + ansible.builtin.apt: + name: "zabbix-agent*" + state: "absent" + + # install agent + - name: "install agent" + ansible.builtin.apt: + name: "{{ item }}" + state: "present" + update_cache: true + when: 'ansible_os_family == "Debian"' + loop: + - "zabbix-agent2" + - "zabbix-agent2-plugin-*" + + + # install repository - suse + - name: "install repository" + when: 'ansible_os_family == "Suse"' + block: + + # remove old agent + - name: "remove old agent" + ansible.builtin.zypper: + name: "zabbix-agent*" + state: "absent" + + # install agent + - name: "install agent" + ansible.builtin.zypper: + name: "{{ item }}" + disable_recommends: false + state: "present" + when: 'ansible_os_family == "Suse"' + loop: + - "zabbix-agent2" + - "zabbix-agent2-plugin-*" + + +# install sudoers file +- name: "install sudoers file" + ansible.builtin.template: + src: "templates/sudoers.d/zabbix.j2" + dest: "/etc/sudoers.d/zabbix" + owner: "root" + group: "root" + mode: "0440" + when: "zabbix_sudo_user" diff --git a/tasks/main.yaml b/tasks/main.yaml new file mode 100644 index 0000000..6ca7c0d --- /dev/null +++ b/tasks/main.yaml @@ -0,0 +1,34 @@ +--- + +# load variables +- name: "include os specific vars" + ansible.builtin.include_vars: "{{ ansible_os_family }}.yaml" + tags: + - "zabbix_agent" + - "zabbix_agent_prereq" + - "zabbix_agent_install" + - "zabbix_agent_config" + + +# zabbix-agent prerequisites +- name: "zabbix-agent prerequisites" + ansible.builtin.import_tasks: "prerequisites.yaml" + tags: + - "zabbix_agent" + - "zabbix_agent_prereq" + + +# zabbix-agent install +- name: "zabbix-agent install" + ansible.builtin.import_tasks: "install.yaml" + tags: + - "zabbix_agent" + - "zabbix_agent_install" + + +# zabbix-agent config +- name: "zabbix-agent config" + ansible.builtin.import_tasks: "config.yaml" + tags: + - "zabbix_agent" + - "zabbix_agent_config" diff --git a/tasks/prerequisites.yaml b/tasks/prerequisites.yaml new file mode 100644 index 0000000..3acd9cd --- /dev/null +++ b/tasks/prerequisites.yaml @@ -0,0 +1,61 @@ +--- + +# find current zabbix version +- name: "check for old zabbix-release" + ansible.builtin.shell: + cmd: "zabbix_agent2 --version | head -n 1" + changed_when: false + failed_when: false + ignore_errors: true + register: "zabbix_current_version" + +# install repository +- name: "install repository" + when: "zabbix_major_version not in zabbix_current_version.stdout" + block: + + # install repository - debian + - name: "install repository" + when: 'ansible_os_family == "Debian"' + block: + + - name: "remove old version" + ansible.builtin.apt: + name: "zabbix-release" + state: "absent" + purge: true + + - name: "install zabbix-release" + ansible.builtin.apt: + deb: "{{ zabbix_repo_url[ansible_distribution][ansible_distribution_major_version | int] }}" + state: "present" + force: true + + - name: "refresh apt cache" + ansible.builtin.apt: + update_cache: true + + + # install repository - suse + - name: "install repository" + when: 'ansible_os_family == "Suse"' + block: + + - name: "remove old version" + ansible.builtin.zypper: + name: "zabbix-releas" + state: "absent" + + - name: "install zabbix-release" + ansible.builtin.zypper: + name: "{{ zabbix_repo_url[ansible_distribution_major_version | int] }}" + state: "present" + disable_recommends: false + nosignature: true + validate_certs: true + + - name: "import gpg key" + community.general.zypper_repository: + name: "Zabbix Official Repository" + auto_import_keys: true + runrefresh: true diff --git a/templates/sudoers.d/zabbix.j2 b/templates/sudoers.d/zabbix.j2 new file mode 100644 index 0000000..d93b9e5 --- /dev/null +++ b/templates/sudoers.d/zabbix.j2 @@ -0,0 +1 @@ +zabbix ALL=(ALL) NOPASSWD: ALL diff --git a/templates/zabbix/zabbix_agent.conf.j2 b/templates/zabbix/zabbix_agent.conf.j2 new file mode 100644 index 0000000..74d9b2d --- /dev/null +++ b/templates/zabbix/zabbix_agent.conf.j2 @@ -0,0 +1,25 @@ +# general +Hostname={{ zabbix_agent_hostname | default(inventory_hostname) }} +Server={{ zabbix_proxy_address }} +ServerActive={{ zabbix_proxy_address }} +ListenPort=10050 +HostMetadataItem=system.uname +HostInterface={{ zabbix_agent_hostinterface | default(inventory_hostname) }} +AllowKey=system.run[*] +Timeout=30 +LogType=system +DebugLevel=1 + +{% if zabbix_agent_psk_enable %} +# psk +TLSConnect=psk +TLSAccept=psk +TLSPSKIdentity={{ zabbix_agent_psk_id }} +TLSPSKFile=/etc/zabbix/zabbix_agent.psk +{% endif %} + +# advanced parameters +Include=/etc/zabbix/zabbix_agent2.d/*.conf +Include=/etc/zabbix/zabbix_agent2.d/plugins.d/*.conf +PluginSocket=/run/zabbix/agent.plugin.sock +ControlSocket=/run/zabbix/agent.sock diff --git a/templates/zabbix/zabbix_agent.psk.j2 b/templates/zabbix/zabbix_agent.psk.j2 new file mode 100644 index 0000000..2c0c382 --- /dev/null +++ b/templates/zabbix/zabbix_agent.psk.j2 @@ -0,0 +1 @@ +{{ zabbix_agent_psk }} diff --git a/vars/Debian.yaml b/vars/Debian.yaml new file mode 100644 index 0000000..13c7e9d --- /dev/null +++ b/vars/Debian.yaml @@ -0,0 +1,15 @@ +--- + +# zabbix repository url +zabbix_repo_url: + Debian: + 12: + "https://repo.zabbix.com/zabbix/{{ zabbix_major_version }}/release/debian/pool/main/z/zabbix-release/\ + zabbix-release_latest_{{ zabbix_major_version }}+debian12_all.deb" + Ubuntu: + 24: + "https://repo.zabbix.com/zabbix/{{ zabbix_major_version }}/release/ubuntu/pool/main/z/zabbix-release/\ + zabbix-release_latest_{{ zabbix_major_version }}+ubuntu24.04_all.deb" + 22: + "https://repo.zabbix.com/zabbix/{{ zabbix_major_version }}/release/ubuntu/pool/main/z/zabbix-release/\ + zabbix-release_latest_{{ zabbix_major_version }}+ubuntu22.04_all.deb" diff --git a/vars/Suse.yaml b/vars/Suse.yaml new file mode 100644 index 0000000..0381f54 --- /dev/null +++ b/vars/Suse.yaml @@ -0,0 +1,7 @@ +--- + +# zabbix repository url +zabbix_repo_url: + 15: + "https://repo.zabbix.com/zabbix/{{ zabbix_major_version }}/release/sles/\ + 15/noarch/zabbix-release-latest-{{ zabbix_major_version }}.sles15.noarch.rpm"