Skip to content

Chapter 2 - Ansible and Python mismatch #604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jamesprajs opened this issue Apr 4, 2025 · 0 comments
Open

Chapter 2 - Ansible and Python mismatch #604

jamesprajs opened this issue Apr 4, 2025 · 0 comments

Comments

@jamesprajs
Copy link

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:

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

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:

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

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:
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

---
- 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant