RAW: update agents and plugins (the API-way) (without CheckMK collection in Ansible)

Hello All, just wanted to share my latest Ansible playbook i use for deploying agent-updates after updating/upgrading the CMK server on a RAW edition.

As the RAW edition does not offer a mechanism to update agents (and plugins) i had to devise a way to still be able to facilitate a large number of hosts via Ansible.

I know that there is a very fine and functional Ansible collection for CheckMK deployment, however for the cases where one is not able to install/use this for any reason i have created this alternative.

In the past i have created a playbook which would only work if it were run over the whole inventory.
This new playbook offers modularity, as it no longer depends on having the monitoring host as part of a/the playbook.
Instead it queries the CMK-Server over the API for details, and then takes it from there.

Additional Information:

  • This playbook creates/manipulates a path of /usr/local/install/packages as a/the source for installation.
  • The last task in the playbook is aimed solely for when the agent is only allowed to communicate over SSH, as it disables the xinetd service → disable/comment this task if this is not the case.
  • This playbook will update plugins which were previously placed on the monitoring host when installed (and available on the server, referenced under Setup → Agents → Linux).

The playbook:

---
# this playbook does not work on SLES 12.x hosts, it complains about the zypper module
# still investigating as to what is causing this.

- hosts: all
  vars:
    monitor_host: 'My_CheckMK_Server'
    monitor_site: 'My_CheckMK_Site'
    download_path: '/usr/local/install/packages'
    plugin_path: '/usr/lib/check_mk_agent/plugins'
    api_user: 'My_Automation_user'
    api_password: 'My_automation_user_password'

  tasks:
    - name: Cleanup packages directory before installing (if it exists)
      ansible.builtin.file:
        path: "{{ download_path }}"
        state: absent

    - name: Create default directories for installing
      ansible.builtin.file:
        path: "{{ download_path }}"
        recurse: true
        state: directory
        owner: root
        group: root
        mode: 0775

    - name: Query monitoring server for running version
      ansible.builtin.uri:
        url: "https://{{ monitor_host }}//{{ monitor_site }}/check_mk/api/1.0/version"
        headers:
          Content-Type: "application/json"
          Accept: "*/*"
          Authorization: "Bearer {{ api_user }} {{ api_password }}"
        method: GET
        return_content: true
      register: cmk_version

    - name: Download and install current agent version for APT-based hosts
      block:
        - name: Copy agent file to APT-based hosts
          ansible.builtin.get_url:
            url: "https://{{ monitor_host }}/{{ monitor_site }}/check_mk/agents/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1_all.deb"
            dest: "/usr/local/install/packages/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1_all.deb"
            mode: "0760"

        - name: Install Agent package for APT-based hosts
          ansible.builtin.apt:
            deb: "{{ download_path }}/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1_all.deb"
            allow_downgrade: yes
          become: yes
      when:
        - ansible_pkg_mgr == "apt"

    - name: Download and install current agent version for YUM-based hosts
      block:
        - name: Copy agent file to YUM-based hosts
          ansible.builtin.get_url:
            url: "https://{{ monitor_host }}/{{ monitor_site }}/check_mk/agents/check-mk-agent-{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            dest: "/usr/local/install/packages/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            mode: "0760"

        - name: Install Agent package for YUM-based hosts
          ansible.builtin.yum:
            name: "{{ download_path }}/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            allow_downgrade: true
            state: present
            disable_gpg_check: yes
      when:
        - ansible_pkg_mgr == "yum"

    - name: Download and install current agent version for DNF-based hosts
      block:
        - name: Copy agent file to DNF-based hosts
          ansible.builtin.get_url:
            url: "https://{{ monitor_host }}/{{ monitor_site }}/check_mk/agents/check-mk-agent-{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            dest: "/usr/local/install/packages/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4]}}-1.noarch.rpm"
            mode: "0760"

        - name: Install Agent package for DNF-based hosts
          ansible.builtin.dnf:
            name: "{{ download_path }}//check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            allow_downgrade: true
            state: present
            disable_gpg_check: yes
      when:
        - ansible_pkg_mgr == "dnf"

    - name: Download and install current agent version for ZYPPER-based hosts
      block:
        - name: Copy agent file to ZYPPER-based hosts
          ansible.builtin.get_url:
            url: "https://{{ monitor_host }}/{{ monitor_site }}/check_mk/agents/check-mk-agent-{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            dest: "/usr/local/install/packages/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            mode: "0760"

        - name: Install Agent package for ZYPPER-based hosts
          community.general.zypper:
            name: "{{ download_path }}//check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1.noarch.rpm"
            force: true
            state: present
            disable_gpg_check: yes
          environment:
            ZYPP_LOCK_TIMEOUT: 30
      when:
        - ansible_pkg_mgr == "zypper"

    - name: find installed plugins in main plugins directory
      ansible.builtin.find:
        paths: "{{ plugin_path }}"
        file_type: file
        recurse: yes
      register: plugins_main

    - name: Set paths of found plugins as fact
      ansible.builtin.set_fact:
        plugins_main_found: "{{ plugins_main | json_query('files[*].path') }}"

    - name: Update found plugins with versions from monitoring host
      ansible.builtin.get_url:
        url: "https://{{ monitor_host }}/{{ monitor_site }}/check_mk/agents/plugins/{{ item | basename }}"
        dest: "{{ item }}"
        force: true
      with_items:
        - "{{ plugins_main_found }}"
      ignore_errors: true

    - name: Adapt plugin settings on APT-based hosts
      block:
        - name: Check presense of mk_apt
          ansible.builtin.stat:
            path: /usr/lib/check_mk_agent/plugins/3600/mk_apt
          register: apt_plugin

        - name: update setting in mk_apt script to use dist-upgrade
          ansible.builtin.lineinfile:
            path: /usr/lib/check_mk_agent/plugins/3600/mk_apt
            regexp: '^UPGRADE=.*'
            line: UPGRADE=dist-upgrade
          when:
            - apt_plugin.stat.exists
      when:
        - ansible_pkg_mgr == "apt"

    - name: Disable Unwanted CheckMK Services
      ansible.builtin.systemd:
        name: cmk-agent-ctl-daemon
        masked: yes

I hope by sharing this you can take advantage of automating your deployment of agents/existing plugins if you are unable to use the checkmk collection.

If however you are able to utilize the checkmk collection offered i urge you to make use of it, as there is a lot more/broader support for it.

  • Glowsome
1 Like