In our infrastructure, we mostly use Gentoo for our servers. For anyone who doesn’t know Gentoo: this Linux distribution compiles packages on the server. Upgrades take a bit more time, but on the other hand the installation can be adjusted to specific requirements: need debug symbols on a dev or staging platform? No problem, compile them in. Want to optimize an application? Change the compile parameters and recompile once: done. Like with pre-compiled packages, this approach has ups and downs.

One occasional problem we see is a missing psycopg2 package if a system upgrade bumped the Python version. The package is required on PostgreSQL servers for the Ansible modules. Of course the Playbook will fail anyway if the package is not there, but why not check upfront if it is available? Saves trouble debugging later on.

Any Playbook which uses a PostgreSQL module includes a small Playbook at the beginning:

  - name: Check if psycopg2 is installed
    include_tasks:
      file: "{{ inventory_dir }}/playbooks/lib/check-psycopg2.yml"
    tags:
      - check
      - psycopg2

And the check-psycopg2.yml Playbook:

---

# make sure that the Python psycopg2 module is installed
# otherwise the remaining Ansible PostgreSQL modules won't work

- name: Python interpreter
  ansible.builtin.debug:
    msg: "Python interpreter{{':'}} {{ ansible_python.executable }}"

- name: Check if psycopg2 is installed
  ansible.builtin.command:
    cmd: "{{ ansible_python.executable }} -c 'import psycopg2'"
  changed_when: false

This piece of code will import the psycopg2 module using the currently used Python interpreter on the server. Keep in mind that Ansible might use a different interpreter. The interpreter can be auto discovered, or set in the inventory. That’s why the module is sometimes missing on the server, if Ansible is not using the default Python for any reason.