Ansible ist ein Programm, welches bei der Verwaltung von Servern sehr nützlich ist. Dieser Artikel beschreibt die Lösung zu einem technischen Problem, das für Endanwender nicht relevant ist.

Oft werden Python-Programme in Virtual Environments vom System-Python getrennt. Für nur ein einzelnes Projekt benötigte Pakete müssen dadurch nicht systemweit installieren werden. Das hilft dabei, ungewollte Nebeneffekte von Updates auszuschließen.
Bei Modulint wird Ansible deswegen in einer Python Virtual Environment ausgeführt.

Abhängigkeiten bei Modulen von Drittanbietern

Letzte Woche wollten wir ein neues Modul einsetzen. Python beschwerte sich mit der Fehlermeldung:


fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "module_stderr": "", "module_stdout": "Traceback (most recent call last):\r\n File \"/tmp/ansible_8znsJd/ansible_module_yedit.py\", line 142, in \r\n import yaml\r\nImportError: No module named yaml\r\n", "msg": "MODULE FAILURE"}

Das neue Modul wollte mittels import yaml die PyYAML Bibliothek lädt. Diese Meldung kam, obwohl die erforderlichen Pakete im Virtual Environment installiert waren.

Ansible verwendete den systemweiten Python-Interpreter

Es stellte sich heraus, dass der falsche Python-Interpreter verwendet wurde.


head /home/developer/virtualEnv/bin/ansible-playbook -n 1
#!/usr/bin/python

/usr/bin/python ist der systemweite Python-Interpreter. Dieser weiß nichts von unseren Programmbibliotheken in der Virtual Environment.

Deswegen musste der Eintrag in den ausführbaren Ansible-Dateien in virtualEnv/bin/ansible* geändert werden:

#!/home/developer/virtualEnv/bin/python

Ab sofort verwendet Ansible den Python-Interpreter der Virtual Environment. Python sucht damit auch im site-packages Ordner der Virtual Environment nach zu ladenden Paketen gesucht. Pakete werden bei Installation durch pip oder easy_install dort abgelegt.

Da das yaml Paket gefunden wird, verschwindet auch die Fehlermeldung!

Vorsicht:
Der beschriebene Ansatz löst nicht alle Probleme dieser art. Nur Module, die auf dem lokalen Rechner ausgeführt werden, profitieren von der Änderung. Dies betrifft zum Beispiel mittels den Ansible-Befehlen local_action oder delegate_to: localhost ausgeführte Aktionen. Soll das Modul mit Abhängigkeiten auf entfernten Rechnern ausgeführt werden, muss für diese ebenfalls der richtige Python Interpreter verwendet werden. Mit Hilfe der Variable ansible_python_interpreter kann der Python Interpreter auf dem entfernten System, welches in einer Virtual Environment liegt, angegeben werden.