Einrichten von Ansible im Virtualenv mit Python3

Datum

Obwohl Python2 bald EoL ist, ist es, zumindest meines Wissens nach, immer noch der Standard für Ansible in VirtualEnvs bzw. überhaupt der Unterbau für Ansible.

Aus der Dokumentation:

Ansible 2.5 and above have support for Python 3. Previous to 2.5, the Python 3 support was considered a tech preview.

Das zeigt sich besonders gut bei z.B. CentOS 7 wo man per epel Repo die aktuelle Ansible-Version erhalten kann:

Verfügbare Pakete
Name       : ansible
Architektur : noarch
Version    : 2.8.0
Ausgabe    : 2.el7
Größe : 15 M
Quelle      : epel/x86_64
...

welche allerdings Python 2 als Unterbau verwendet:

[rasputin@localhost ~]$ ansible --version
ansible 2.8.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/home/rasputin/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr  9 2019, 14:30:50) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

Hier möchte ich am Beispiel von CentOS 7 zeigen, wie man verschiedene virtualenvs für ansible mit Python 3 einrichtet.

Vorbereitungen

Um Python 3 in CentOS 7 zu installieren zu können, benötigen wir zuerst das epel (Extra Packages for Enterprise Linux) Repo:

yum install -y epel-release

Nun aktualisieren wir erst einmal unseren Paket-Cache:
yum makecache fast

Bei der aktuellen Version (CentOS Linux release 7.6.1810) folgende Python3-Version verfügbar:

[root@localhost ~]# yum info python36
...
Installierte Pakete
Name       : python36
Architektur : x86_64
Version    : 3.6.8
Ausgabe    : 1.el7
Größe : 39 k
Quelle      : installed
Aus Quelle  : epel
...
Insgesamt benötigen wir folgende Pakete:
  • python36
  • python36-pip
  • python36-virtualenv
  • python36-pyOpenSSL

yum install -y python36-pip python36 python36-virtualenv python36-pyOpenSSL

Überprüfen der Installationspfade

Wenn man nun nicht genau weiss wie die entsprechenden Binaries für z.B: pip oder virtualenv heißen, dann kann man einfach mal schauen was mit den entsprechenden Paketen installiert wurde:

[root@localhost ~]# rpm -ql python36-pip | grep bin
/usr/bin/pip3
/usr/bin/pip3.6
[root@localhost ~]# rpm -ql python36-virtualenv | grep bin
/usr/bin/py3-virtualenv
/usr/bin/virtualenv-3
/usr/bin/virtualenv-3.6

Installation von Ansible im Virtualenv

Zuerst legen wir per /usr/bin/virtualenv-3.6 ansible_2.8.0 die passende Struktur an.

[rasputin@localhost ~]$ /usr/bin/virtualenv-3.6 ansible_2.8.0
Using base prefix '/usr'
New python executable in /home/rasputin/ansible_2.8.0/bin/python3.6
Also creating executable in /home/rasputin/ansible_2.8.0/bin/python
Installing setuptools, pip, wheel...done.
[rasputin@localhost ~]$ tree -L 1 ansible_2.8.0/
ansible_2.8.0/
├── bin
├── include
├── lib
├── lib64 -> lib
└── pip-selfcheck.json

Nun aktivieren wir das virtualenv per source ansible_2.8.0/bin/activate führen dann ein Upgrade der setuptools durch.

[rasputin@localhost ~]$ source ansible_2.8.0/bin/activate
(ansible_2.8.0) [rasputin@localhost ~]$ pip3 install --upgrade setuptools
Requirement already up-to-date: setuptools in ./ansible_2.8.0/lib/python3.6/site-packages (41.0.1)

Jetzt wird Ansible in der entsprechenden Version per pip3 install ansible==<VERSION> im virtualenv installiert.

(ansible_2.8.0) [rasputin@localhost ~]$ pip3 install ansible==2.8.0
Collecting ansible==2.8.0
Collecting jinja2 (from ansible==2.8.0)
  Using cached https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl
Collecting cryptography (from ansible==2.8.0)
  Using cached https://files.pythonhosted.org/packages/5b/12/b0409a94dad366d98a8eee2a77678c7a73aafd8c0e4b835abea634ea3896/cryptography-2.6.1-cp34-abi3-manylinux1_x86_64.whl
Collecting PyYAML (from ansible==2.8.0)
Collecting MarkupSafe>=0.23 (from jinja2->ansible==2.8.0)
  Using cached https://files.pythonhosted.org/packages/b2/5f/23e0023be6bb885d00ffbefad2942bc51a620328ee910f64abe5a8d18dd1/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl
Collecting asn1crypto>=0.21.0 (from cryptography->ansible==2.8.0)
  Using cached https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl
Collecting six>=1.4.1 (from cryptography->ansible==2.8.0)
  Using cached https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl
Collecting cffi!=1.11.3,>=1.8 (from cryptography->ansible==2.8.0)
  Using cached https://files.pythonhosted.org/packages/5f/bf/6aa1925384c23ffeb579e97a5569eb9abce41b6310b329352b8252cee1c3/cffi-1.12.3-cp36-cp36m-manylinux1_x86_64.whl
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography->ansible==2.8.0)
Installing collected packages: MarkupSafe, jinja2, asn1crypto, six, pycparser, cffi, cryptography, PyYAML, ansible
Successfully installed MarkupSafe-1.1.1 PyYAML-5.1 ansible-2.8.0 asn1crypto-0.24.0 cffi-1.12.3 cryptography-2.6.1 jinja2-2.10.1 pycparser-2.19 six-1.12.0

Im Grunde hat man nun ein lauffähiges Ansible:

(ansible_2.8.0) [rasputin@localhost ~]$ ansible --version
ansible 2.8.0
  config file = None
  configured module search path = ['/home/rasputin/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/rasputin/ansible_2.8.0/lib/python3.6/site-packages/ansible
  executable location = /home/rasputin/ansible_2.8.0/bin/ansible
  python version = 3.6.8 (default, Apr 25 2019, 21:02:35) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

Und wie man sieht läuft hier alles unter Python 3.
Natürlich kann man sich noch weitere Module und Libaries per pip3 install ... installieren, da mittlerweile fast alle Python-Packages auch in Python 3 funktionieren.

Autor
Kategorien Ansible, Linux

PRTG Map