Skip to main content
RunBook Academy

AnsibleVI · Configuration and PrecedenceConfiguration and precedence

Interpreter discovery, configured

Advanced⏱ ~17 minansible-core

What you'll learn

  • Describe how Ansible discovers a Python interpreter on a managed node
  • Read the discovery warning as a statement about future instability rather than a current fault
  • Pin ansible_python_interpreter per group instead of silencing the warning globally
  • Recognise that interpreter_python accepts any string, so a typo becomes an interpreter path

Prerequisites

Verified against ansible-core 2.21.x · ansible (community package) 14.x · Python (controller) 3.12+ · ansible-lint 26.x · Molecule 26.x · Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL / Rocky / AlmaLinux 9.x · 2026-08-11

Not yet marked complete on this device.

Almost every Ansible module is Python that gets copied to the managed node and run there. Something has to decide which Python runs it, and on a host with python3.9, python3.12 and /usr/bin/python3 all present, that decision has consequences — the three do not have the same libraries installed.

INTERPRETER_PYTHON is the setting that makes the decision. Its default is auto, and auto produces a warning that most people silence.

The setting

Read-only / Safethe default
$ ansible-config dump | grep '^INTERPRETER_PYTHON'
INTERPRETER_PYTHON(default) = auto

It is set in [defaults] as interpreter_python, in the environment as ANSIBLE_PYTHON_INTERPRETER, and — most usefully — as the inventory variable ansible_python_interpreter.

The supported discovery modes on 2.21.3 are auto and auto_silent. The auto_legacy and auto_legacy_silent modes existed for compatibility with older releases that always defaulted to /usr/bin/python3.

What discovery actually does

This is the part that makes the warning make sense.

Ansible runs a short shell bootstrap on the managed node that tests each candidate interpreter in turn with command -v, and takes the first one found. The candidate list is itself a setting, INTERPRETER_PYTHON_FALLBACK, and on 2.21.3 its default is exactly:

Read-only / Safethe search order, in order
$ ansible-config dump | grep '^INTERPRETER_PYTHON_FALLBACK'
INTERPRETER_PYTHON_FALLBACK(default) = ['python3.14', 'python3.13', 'python3.12', 'python3.11', 'python3.10', 'python3.9', '/usr/bin/python3', 'python3']

Read that list top-down and the whole problem becomes visible. Newer versions are searched first. A host that today has python3.12 as its newest interpreter runs modules under python3.12. Install python3.13 on it next month — as a dependency of something unrelated, perhaps — and the very next Ansible run silently switches to python3.13.

Nothing about your automation changed. The interpreter did.

If none of the candidates is found, discovery falls back to /usr/bin/python3.

The warning, and what it is telling you

With auto, after a successful discovery, Ansible emits a warning of this form on 2.21.3:

[WARNING]: Host 'web-a1.example.com' is using the discovered Python
interpreter at '/usr/bin/python3.12', but future installation of another
Python interpreter could cause a different interpreter to be discovered.

Read it precisely. It is not saying anything is wrong now. It is saying: this choice is not stable, and nothing will tell you when it changes.

That is a much more serious statement than it appears, because of what differs between two Pythons on the same host. Distribution-provided bindings are installed for one specific interpreter. On a Debian or Ubuntu host, python3-apt is installed for the system Python; if discovery picks a different interpreter that lacks it, the ansible.builtin.apt module fails with a message about being unable to import apt and apt_pkg — on a host where it worked last week, in a run that changed nothing about package management.

The same shape applies to python3-rpm on RHEL-family hosts, to SELinux bindings, and to anything else installed as a distribution Python package.

The right fix: pin it where the fact belongs

The interpreter is a property of the host, so it belongs in inventory, per group, next to the other facts about that host family:

# inventory/production/group_vars/ubuntu_2404.yml
ansible_python_interpreter: /usr/bin/python3

# inventory/production/group_vars/rocky_9.yml
ansible_python_interpreter: /usr/bin/python3.9

This is better than a global setting in three ways that matter.

It is correct per host family. A single global value is wrong for any estate with more than one distribution generation, which is every estate that has been running for a while.

It is reviewable. The value is in Git, in the group’s variables file, and changing it is a commit somebody approves — unlike an interpreter that changes because apt pulled in a new Python.

It survives the thing the warning was about. Installing python3.13 on a pinned host changes nothing, because nothing is being discovered.

Knowledge check

Knowledge check · 4 questions

  1. Q1. The discovery warning says a different interpreter could be discovered in future. Why is that a serious statement rather than routine noise?

  2. Q2. Setting interpreter_python = auto_silent changes which Python interpreter Ansible selects on the managed node.

  3. Q3. Which are true of interpreter discovery on ansible-core 2.21.3? Select all that apply.

  4. Q4. An operator sets ANSIBLE_PYTHON_INTERPRETER=auto_silnet, misspelling auto_silent. What happens?

Passing score: 75%. Answers are checked in this browser.