geerlingguy / geerlingguy/ansible-for-devops
Chapter 2 - Ansible and Python mismatch
- Dominant language
- Python
- Stars
- 9.9k
- Forks
- 3.8k
- PR merge metrics
- No merged PRs in 30d
Description
I converted an old Macbook Pro to Linux Mint (Linux Mint 22.1
) and tried to follow the example in Chapter two of your book and ran into a nightmare. After a long chat with ChatGPT:
Here's a summary of our discussion and the key takeaways:
---
## 🧵 **Problem Summary**
You were trying to use **Ansible with a Rocky Linux 8 Vagrant VM** and ran into these issues:
1. ❌ **Ansible failed with**:
`"MODULE FAILURE: No start of json char found"`
This occurred when using modules like `dnf`, indicating broken Python compatibility.
2. ❌ **Rocky Linux 8 default Python** is **3.6 (platform-python)**, which:
- Is too old for modern Ansible (v2.14+ requires Python ≥3.8)
- Has system-specific behavior that can confuse Ansible
3. ❌ You tried installing Ansible 2.12 (compatible with Python 3.6), but:
- Your host system uses **Python 3.12**
- Ansible 2.12 is **incompatible with Python 3.12**, resulting in `_AnsiblePathHookFinder` errors
4. ❌ You tried installing Python 3.9 using `apt`, but Mint's base repos didn’t include it
---
## ✅ Working Solution (Step-by-Step)
### 🔧 1. **Install a compatible Python (3.9 or 3.10) on your host**
Using the **deadsnakes PPA**, you can install Python 3.10 like so:
```bash
sudo apt install -y software-properties-common
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update
sudo apt install -y python3.10 python3.10-venv
```
---
### 🐍 2. **Create a virtual environment for Ansible 2.12**
```bash
python3.10 -m venv ~/.venvs/ansible-2.12
source ~/.venvs/ansible-2.12/bin/activate
pip install ansible-core==2.12.3
```
---
### 📦 3. **Run Ansible from that environment**
This will allow Ansible to run against the **Rocky Linux 8 VM** using **platform-python (3.6)** without errors.
Use this in your `Vagrantfile`:
```ruby
ansible.extra_vars = {
ansible_python_interpreter: "/usr/libexec/platform-python"
}
```
And keep your Ansible version at **2.12.x**, which supports Python 3.6.
---
## ✅ Alternatives you considered:
- Installing Python 3.9 in the Rocky guest → failed due to missing `dnf` bindings
- Using newer Ansible → failed due to Python 3.6 on guest
- Using raw commands instead of Ansible modules → possible workaround
Here's the **new working `Vagrantfile`** that pairs perfectly with:
- **Ansible 2.12** (installed in a Python 3.10 virtual environment on your host)
- **Rocky Linux 8 guest**
- **The system Python (`platform-python`, Python 3.6)** on the guest VM — which is fully compatible with Ansible 2.12 for DNF, systemd, etc.
---
## ✅ Final Working `Vagrantfile`
```ruby
Vagrant.configure("2") do |config|
config.vm.box = "geerlingguy/rockylinux8"
config.vm.hostname = "rockyvm"
config.vm.network "private_network", type: "dhcp"
# Optional: allocate more resources
config.vm.provider "virtualbox" do |vb|
vb.memory = 2048
vb.cpus = 2
end
# ✅ Use the system Python that supports Ansible 2.12 modules (like dnf)
config.vm.provision "ansible" do |ansible|
ansible.compatibility_mode = "2.0"
ansible.playbook = "playbook.yml"
ansible.extra_vars = {
ansible_python_interpreter: "/usr/libexec/platform-python"
}
end
end
```
---
## ✅ Notes
- This assumes you've activated your **Python 3.10 virtual environment** and installed **Ansible 2.12**:
```bash
source ~/.venvs/ansible-2.12/bin/activate
ansible --version # should show 2.12.x
```
- `platform-python` is Rocky 8's internal Python 3.6.8, which works **only** with Ansible 2.12 or earlier.
---
## ✅ Matching `playbook.yml` Example
```yaml
---
- hosts: all
become: true
gather_facts: true
tasks:
- name: Show which Python is being used
raw: which python3
register: python_path
- name: Print Python path
debug:
var: python_path.stdout
- name: Install chrony using dnf module
dnf:
name: chrony
state: present
- name: Ensure chronyd is running
service:
name: chronyd
state: started
enabled: yes
```
---
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.