David Moreau Simard

2 minute read

(Edit: See at the end)

I can’t get enough of this Ansible thing, it’s great and makes my life easier.

Sometimes there’s this little awesome feature that is in a pull request or has already landed in the development branch. You can’t wait to use but it won’t be shipped until the next release of Ansible.. and sometimes that takes a while.

What do you do in the meantime ?

Dawg, I heard you liked Ansible so I patched your Ansible with Ansible ! (sorry)

In practice, it looks like this:

# This isn't going to land until Ansible 2.4, patch it in until then
# https://github.com/ansible/ansible/pull/24184
- name: Ensure the sensu_check module supports the 'ttl' parameter
  gather_facts: true
  hosts: localhost
  tasks:
    # Import Ansible running from the current python interpreter
    - name: Retrieve Ansible location
      command: |
        {{ hostvars[inventory_hostname]['ansible_playbook_python'] }} \
          -c "import os,ansible; print(os.path.dirname(ansible.__file__))"
      changed_when: false
      register: ansible_location

    # Appending .patch to a GitHub commit magically returns a patch file
    - name: Retrieve sensu_check TTL patch
      get_url:
        url: "https://github.com/ansible/ansible/commit/020fcb38451ad2613d815eeae52ec1ab53562fbe.patch"
        dest: "/tmp/sensu_check_ttl.patch"

    # This is idempotent, if the file is already patched it just returns 'ok'
    - name: Patch sensu_check module (ttl)
      patch:
        src: "/tmp/sensu_check_ttl.patch"
        dest: "{{ ansible_location.stdout }}/modules/monitoring/sensu_check.py"

$ ansible-playbook -i hosts patch.yml

PLAY [Ensure the sensu_check module supports the 'ttl' parameter] *************
TASK [Gathering Facts] ********************************************************
ok: [localhost]

TASK [Retrieve Ansible location] **********************************************
ok: [localhost]

TASK [Retrieve sensu_check TTL patch] *****************************************
changed: [localhost]

TASK [Patch sensu_check module] ***********************************************
changed: [localhost]

PLAY RECAP ********************************************************************
localhost                  : ok=4    changed=2    unreachable=0    failed=0

Edit

Some folks have (rightfully) pointed out that this isn’t the right way to carry modified versions of Ansible modules. I should have made obvious that this was just a fun experiment to see if it was possible to use Ansible to patch itself.

If you’re interested in carrying patches, you’ll likely want to include the whole file in your ANSIBLE_LIBRARY (or ANSIBLE_ACTION_PLUGINS) path. For the particular example above, I would have the full patched version of sensu_check.py in there.

It turns out there might be weird issues doing this sometimes though, so you’ll want to be on the look out in case you are hitting an issue documented here.

Ansible pro (and ansible-lint author!) Will Thames has a great approach to documenting the different patched modules he is using: