Daily Shaarli

All links of one day in a single page.

February 22, 2024

A simple logger of Ansible role git state

With frequent changes to my Ansible roles it often becomes tricky to keep track of which version of a particular role was executed for a particular play.

This is not thoroughly tested yet, but my approach is simple: each role contains a task that writes its git repo state (a git log formatted one-liner containing last commit hash, date, author, etc.).
These tasks are set to write to a log-file per inventory host, which is for two reasons: to avoid drowning in the default log file defined by log_path in ansible.cfg, and because log_path cannot be overridden by a play or role.

This results in a log-file (one per inventory host) looking something like this:

Started playbook execution at 2024-02-22 12:34:32.327042
Role 'locales' last commit caa6355 2024-02-21 23:38:31 +0100 by solarchemist
Role 'digikam' last commit 16f0643 2024-02-21 22:50:49 +0100 by solarchemist
Playbook 'workstation' last commit 4775cf7 2024-02-20 22:53:56 +0100 by solarchemist
Ended playbook execution at 2024-02-22 12:34:55.913856

My implementation illustrated in code below.

In a role:

- name: Log the last commit and git repo status to playbook log-file
  local_action: >
    shell git -C {{ role_path }} log
    --pretty="Role '{{ role_name }}' last commit %h %ci by %cn" -1 >>
    logbook-{{ inventory_hostname }}.log
  args: { chdir: "{{ playbook_dir }}" }
  become: true
  become_user: "{{ local_user }}"

In the playbook:

  vars:
     local_user: "{{ lookup('env', 'USER') }}"

  pre_tasks:
    - name: Write a start message to the playbook log
      ansible.builtin.shell: >
        printf "\nStarted playbook execution at {{ now() }}\n" >> logbook-{{ inventory_hostname }}.log
      run_once: true
      delegate_to: localhost
      args: { chdir: "{{ playbook_dir }}" }
      become: true
      become_user: "{{ local_user }}"
      changed_when: true
      tags: always

  tasks: [...]

  post_tasks:
    - name: Log the current commit of this playbook
      local_action: >
        shell git log
        --pretty="Playbook '{{ playbook_dir | basename }}' last commit %h %ci by %cn" -1
        >> logbook-{{ inventory_hostname }}.log
      args: { chdir: "{{ playbook_dir }}" }
      become: true
      become_user: "{{ local_user }}"
      tags: always
    - name: Write an end message to the playbook log
      ansible.builtin.shell: >
        echo "Ended playbook execution at {{ now() }}" >> logbook-{{ inventory_hostname }}.log
      run_once: true
      delegate_to: localhost
      args: { chdir: "{{ playbook_dir }}" }
      become: true
      become_user: "{{ local_user }}"
      changed_when: true
      tags: always