Ansible'da Python Interpreter Not Found Hatası
Selamlar arkadaşlar, bu yazımda Ansible kullananların eninde sonunda karşısına çıkan o klasik hatayı, yani 'python interpreter not found' veya 'ansible-core requires a minimum of Python version 3.8' uyarısını biraz didikleyeceğiz. Konu sıkıcı gibi durabilir ama açıkçası bu hatanın bir kere doğru çözüldüğünü gördüğünüzde, fresh bir VM ya da minimal container karşınıza çıktığında elin ayağın titremiyor. Hadi başlayalım.
Hata neden çıkıyor?
Ansible'ın çoğu modülü aslında hedef makineye SSH ile push edilen ufak Python script'leri. Yani kontrol makinenizde Ansible olsa bile, asıl iş hedef sunucudaki Python yorumlayıcıyla yapılıyor. Hedefte Python yoksa veya Ansible onu beklenen yerde bulamıyorsa şuna benzer bir mesaj alıyorsunuz:
[WARNING]: No python interpreters found for host server1
fatal: [server1]: FAILED! => {
"msg": "ansible-core requires a minimum of Python version 3.8. Current version: None"
}
Bence en sık tetikleyen üç senaryo şunlar: minimal kurulu cloud image'ları (özellikle Ubuntu minimal, Debian slim), Alpine tabanlı container'lar ve eski RHEL/CentOS sistemleri. RHEL 8 mesela /usr/libexec/platform-python diye bir şey kullanıyor ve auto-discovery bazen bunu seçince paket modülleri huysuzlanıyor.
ansible_python_interpreter ile yolu sabitlemek
En hızlı çözüm interpreter yolunu inventory'de açıkça yazmak. Bunu host bazında veya grup bazında verebilirsiniz:
[all:vars]
ansible_python_interpreter=/usr/bin/python3
[webservers]
server1 ansible_host=10.0.1.10 ansible_python_interpreter=/usr/bin/python3.11
[alpine_hosts]
alpine1 ansible_python_interpreter=/usr/bin/python3
Tabii her host'a tek tek yol yazmak istemiyorsanız ansible.cfg üzerinden auto-discovery'yi de açabilirsiniz:
[defaults]
interpreter_python = auto_silent
auto_silent yerine auto da seçebilirsiniz, fark sadece uyarı satırının basılıp basılmaması. Modern Ansible sürümlerinde INTERPRETER_PYTHON_DISTRO_MAP denen bir iç tablo var; Ansible hedefin distro ve sürümüne bakıp 'bu sistemde Python muhtemelen şuradadır' diyor. Çoğu zaman doğru tahmin ediyor ama RHEL 8 platform-python meselesinde benim tercihim auto'ya güvenmek yerine yolu sabitlemek olur.
raw modülü ile bootstrap
Peki ya hedef makinede gerçekten Python yoksa? İşte bu noktada raw modülü hayat kurtarıyor. Çünkü raw Python beklemez, doğrudan SSH üzerinden komut çalıştırır:
- hosts: new_servers
gather_facts: false
become: true
tasks:
- name: Hedefte Python kuralim
raw: |
if command -v apt-get >/dev/null; then
apt-get update && apt-get install -y python3 python3-apt
elif command -v dnf >/dev/null; then
dnf install -y python3
elif command -v apk >/dev/null; then
apk add --no-cache python3
fi
- name: Artik fact toplayabiliriz
setup:
Buradaki kritik nokta gather_facts: false. Eğer bunu kapatmazsanız Ansible playbook'un en başında fact toplamak için Python aramaya kalkar ve daha ilk task çalışmadan patlarsınız. Önce raw ile Python'u kuruyoruz, sonra setup modülünü manuel çağırıp fact'leri topluyoruz. Bana sorarsanız bu sıralamayı her bootstrap rolünde standart hale getirmek lazım.
Container'lar için de hikaye benzer:
- hosts: containers
gather_facts: false
vars:
ansible_python_interpreter: /usr/bin/python3
pre_tasks:
- name: Container'a Python kur
raw: apt-get update && apt-get install -y python3
Fact caching ile aynı acıyı tekrar tekrar çekmemek
Bootstrap aşamasını geçtikten sonra her playbook çalıştırışınızda fact toplamak hem yavaş hem de gereksiz. ansible.cfg üzerinden fact caching'i açın:
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/ansible_facts
fact_caching_timeout = 86400
smart modu, fact'i daha önce toplanmış host'lar için tekrar toplamıyor. Production'da Redis backend'ini de tercih edebilirsiniz ama jsonfile küçük envanterler için fazlasıyla yeterli.
Sık karşılaşılan tuzaklar
- gather_facts: false unutmak: Bootstrap playbook'unda bunu kapatmazsanız, Python yoksa
setupmodülü hata verir, raw task'ınıza hiç sıra gelmez. - python3-apt'ı atlamak: Debian/Ubuntu'da
aptmodülüpython3-aptpaketine bağımlı. Sadecepython3kurarsanız sonraki paket task'ları 'Could not import python modules: apt, apt_pkg' diye çığlık atar. - platform-python'a güvenmek: RHEL 8'de auto-discovery bazen
/usr/libexec/platform-pythonseçer vednfmodülü dışındaki paket işlerinde tuhaflıklar olur. Açık/usr/bin/python3sabitlemesi daha öngörülebilir. - Alpine'da python3 yerine python aramak: Alpine'da binary doğrudan
python3.pythonsymlink'i yok,ansible_python_interpreter=/usr/bin/pythonyazarsanız bulamaz.
Kapanış
Özetle, bu hatanın iki kalıcı çözümü var: ya interpreter yolunu inventory'de sabitleyin, ya da Python'u raw modülü ile kurup sonra normal akışa devam edin. Şahsi kanaatim, fresh sunucularda bootstrap rolünü her zaman ayrı tutmak ve fact caching'i baştan açmak uzun vadede en az dert çıkaran yol. Umarım faydalı olur, bir sonraki yazıda görüşmek üzere.
