- name: Backup and/or Upgrade MikroTik hosts: mikrotik_routers gather_facts: no vars: backup_dir: /opt/mikrotik_backups/ tasks: # ---------------------------- # Always: identity + timestamp # ---------------------------- - name: Get router identity community.routeros.command: commands: /system identity print register: identity_raw tags: always - name: Parse router name set_fact: router_name: "{{ identity_raw.stdout[0].split(': ')[1] | trim }}" tags: always - name: Get timestamp ansible.builtin.command: date +%Y-%m-%d_%H-%M-%S register: date_out delegate_to: localhost tags: always - name: Set timestamp fact set_fact: ts: "{{ date_out.stdout }}" tags: always # ---------------------------- # Backup (tag: backup) # ---------------------------- - name: Ensure local backup directory exists ansible.builtin.file: path: "{{ backup_dir }}" state: directory mode: "0755" delegate_to: localhost tags: [backup, never] - name: Export router config community.routeros.command: commands: /export terse show-sensitive register: export_cfg tags: [backup, never] - name: Save export locally ansible.builtin.copy: content: "{{ export_cfg.stdout[0] }}" dest: "{{ backup_dir }}/{{ router_name }}-{{ ts }}.rsc" delegate_to: localhost tags: [backup, never] # ---------------------------- # Upgrade (tag: upgrade) # ---------------------------- - name: Check current and latest available package versions community.routeros.command: commands: /system package update check-for-updates register: update_check tags: [upgrade, never] - name: Normalize update output set_fact: _update_text: "{{ update_check.stdout[0] | replace('\r', '') }}" tags: [upgrade, never] # ⬇️ Add this to see exactly what RouterOS returns before parsing - name: Debug raw update output ansible.builtin.debug: msg: "{{ _update_text }}" tags: [upgrade, never] - name: Parse installed and latest versions set_fact: installed_version: >- {{ (_update_text | regex_findall('(?:installed|current)-version:[ ]*([0-9A-Za-z.]+)'))[0] if (_update_text | regex_findall('(?:installed|current)-version:[ ]*([0-9A-Za-z.]+)')) else 'unknown' }} latest_version: >- {{ (_update_text | regex_findall('(?:latest|newest)-version:[ ]*([0-9A-Za-z.]+)'))[0] if (_update_text | regex_findall('(?:latest|newest)-version:[ ]*([0-9A-Za-z.]+)')) else 'unknown' }} tags: [upgrade, never] - name: Fail if versions could not be parsed ansible.builtin.fail: msg: > Could not parse versions from update output. Raw text was: {{ _update_text }} when: installed_version == 'unknown' or latest_version == 'unknown' tags: [upgrade, never] - name: Debug parsed versions ansible.builtin.debug: msg: - "Installed: {{ installed_version }}" - "Latest: {{ latest_version }}" tags: [upgrade, never] - name: Skip upgrade if already on latest ansible.builtin.debug: msg: "Router {{ router_name }} is already on latest version {{ installed_version }}. Skipping upgrade." when: installed_version == latest_version tags: [upgrade, never] - name: Trigger package download and install community.routeros.command: commands: /system package update install register: upgrade_result when: installed_version != latest_version tags: [upgrade, never] - name: Wait for router to come back online after reboot community.routeros.command: commands: /system resource print register: reboot_wait until: reboot_wait is not failed retries: 30 delay: 15 when: - installed_version != latest_version - upgrade_result is not failed tags: [upgrade, never] - name: Confirm upgraded version community.routeros.command: commands: /system resource print register: post_upgrade_info when: installed_version != latest_version tags: [upgrade, never] - name: Show post-upgrade RouterOS version ansible.builtin.debug: msg: "{{ post_upgrade_info.stdout[0] | regex_search('version: .+') }}" when: installed_version != latest_version tags: [upgrade, never]