Ansible: Playbook for updating Agents on hosts (CRE / No CheckMK collection available)

Hi all,

Just wanted to share a/the playbook i have created for these specific cases:

Situation:
In a/the cases where you are running CheckMK RAW edition (or potentially free(not tested))
and want to update agents (and plugins) after a Server update, but are not allowed/able to (for whatever reason) use the CheckMK Ansible collection.

Prerequisites:

  • An Ansible controller with an inventory/host reference (duh) :slight_smile:
  • A functional/erected automation user, with an automation secret set.

Caveats:

  • This playbook will NOT work on SLES/SuSE 12.x hosts.
  • This playbook will NOT install new plugins, it only updates existing ones on a host.

Drilldown of the playbook:

  • playbook will clean a/the path of previously stored files so it will always be fresh/current.
    → i always have a /usr/local/install/ dir with subdirs like:

    • packages
    • source
    • compile
    • iso
  • playbook queries the information from CheckMK server via API/automation user to get a/the current version

  • With version determined it will use a conventional method of ansible.builtin.get_url downloading a/the agent package to the per-determined location (see vars in the playbook)

  • (force-) Install the Agent version downloaded with a/the correct package-manager in previous step correctly on the system.

  • Scan previously installed plugins, and update them accordingly from the CheckMK Server.

  • For APT-based systems changes the mode-reference to UPGRADE=dist-upgrade in the APT-plugin.

  • When (as in my case) only SSH-method is used to pull data from a host, the agent service listening on port 6556 is disabled. (remove/comment out last tasks if this is not wanted)

The Playbook:

---
# this playbook does not work on SLES 12.x hosts, it complains about the zypper module
#

- hosts: all
  vars:
    monitor_host: 'Your_CheckMK_Server'
    monitor_site: 'Your_CheckMK_Sitename'
    download_path: '/usr/local/install/packages'
    plugin_path: '/usr/lib/check_mk_agent/plugins'
    api_user: 'Your_api_User'
    api_password: 'Your_api_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: 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

    - name: Disable Unwanted CheckMK Services
      ansible.builtin.systemd:
        state: stopped
        enabled: no
        name: cmk-agent-ctl-daemon

Note:
Remember, what i am sharing here is not a ‘finalized’ playbook, but something that works on my environment ( 80+ hosts, of different linux flavors (Debian, RockyLinux, SuSE).
→ Windows is omitted, because i do not have/run Windows machines, so i have no way to proof something i write in a/the playbook.

Also this is in no way meant to be an alternative to function as an alternative when the CheckMK Ansible collection is available to you/can be used.
It is/was explicitly created for when you are unable to use it.

Personal opinion:
I felt that the playbook is mature enough to share, however some parts imho can still be refined/optimized to make a/the runtime shorter.
Suggestions regarding this are more then welcome (pref via DM, so it does not clutter this thread).
Updates/suggestions from those DM’s will result when honored in modification of this post, meaning it’s kept current ( and pure)

  • Glowsome
1 Like