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

Just a little Update/revelation i had:
The workings of the playbook depend on the python-version.

For SLES 12.x, or OES18.x SuSE it is required to specify the python2.7 interpreter to make it work.

For some reason SuSE made a jump to python 3.4, and 3.4m, but never went to 3.6 in their old OS’es
Ansible requires either python 2.7 or 3.6 ( the latter is neither on SLES12.x or OES18 available)

So in your hosts (or hosts.yml) you will need to specify this version:

 ansible_python_interpreter: "/usr/bin/python2.7"
  • Glowsome

Just an update regarding the previously posted Ansible playbook.

As the api-response of the version from the CMK server has changed since 2.5.0pX i have adapted the playbook to facilitate both.

See the new code below:

---
# this playbook works on SLES12.x and/or OES18 hosts aslong as the ansible_python_interpreter is specified in the hosts-file to utilize python2.7 ( /usr/bin/python2.7 )

- hosts: all
  vars:
    monitor_host: 'Your_CheckMK-Server'
    monitor_site: 'Your_site_name'
    download_path: '/usr/local/install/packages'
    plugin_path: '/usr/lib/check_mk_agent/plugins'
    api_user: 'Your_Automation_User'
    api_password: 'Your_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 CheckMK < 2.5.0 agent version for APT-based hosts"
      block:
        - name: "Copy agent file to APT-based hosts (CheckMK < 2.5.0)"
          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 (CheckMK < 2.5.0)"
          ansible.builtin.apt:
            deb: "{{ download_path }}/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-4] }}-1_all.deb"
            allow_downgrade: yes
          become: yes

      when:
          - cmk_version.json.versions.checkmk is search(".cre")
          - ansible_pkg_mgr == "apt"

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

        - name: Install Agent package for APT-based hosts (CheckMK 2.5.0+)
          ansible.builtin.apt:
            deb: "{{ download_path }}/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-10] }}-1_all.deb"
            allow_downgrade: yes
          become: yes

      when:
        - cmk_version.json.versions.checkmk is search(".community")
        - ansible_pkg_mgr == "apt"

    - name: Download and install current agent version for YUM-based hosts (CheckMK < 2.5.0)
      block:
        - name: Copy agent file to YUM-based hosts (CheckMK < 2.5.0)
          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 (CheckMK < 2.5.0)
          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:
        - cmk_version.json.versions.checkmk is search(".cre")
        - ansible_pkg_mgr == "yum"

    - name: Download and install current agent version for YUM-based hosts (CheckMK 2.5.0+)
      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[:-10] }}-1.noarch.rpm"
            dest: "/usr/local/install/packages/check-mk-agent_{{ cmk_version.json.versions.checkmk[:-10] }}-1.noarch.rpm"
            mode: "0760"

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

    - name: Download and install current agent version for DNF-based hosts (CheckMK < 2.5.0)
      block:
        - name: Copy agent file to DNF-based hosts (CheckMK < 2.5.0)
          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 (CheckMK < 2.5.0)
          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:
        - cmk_version.json.versions.checkmk is search(".cre")
        - ansible_pkg_mgr == "dnf"


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

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

    - name: Download and install current agent version for ZYPPER-based hosts (CheckMK < 2.5.0)
      block:
        - name: Copy agent file to ZYPPER-based hosts (CheckMK < 2.5.0)
          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 (CheckMK < 2.5.0)
          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:
        - cmk_version.json.versions.checkmk is search(".cre")
        - ansible_pkg_mgr == "zypper"

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

        - name: Install Agent package for ZYPPER-based hosts (CheckMK 2.5.0+)
          community.general.zypper:
            name: "{{ download_path }}//check-mk-agent_{{ cmk_version.json.versions.checkmk[:-10] }}-1.noarch.rpm"
            force: true
            state: present
            disable_gpg_check: yes
          environment:
            ZYPP_LOCK_TIMEOUT: 30
      when:
        - cmk_version.json.versions.checkmk is search(".community")
        - 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"

# Only enable this task when you are using the old/legacy way to communicate with the Agent over SSH only.
    - name: Disable Unwanted CheckMK Services
      ansible.builtin.systemd:
        name: cmk-agent-ctl-daemon
        masked: yes

Please do report if i missed something / playbook errors.

  • Glowsome