Personalmente encontré 3 posibles soluciones a este problema que funcionan bien en diferentes situaciones:
Opción 1: configurada ansible_python_interpreter: /usr/bin/python3
para hosts que se han python3
instalado de manera predeterminada
Creo que este es el método superior para resolver el problema si tiene una forma de agrupar sus hosts por si se han python3
instalado o no de manera predeterminada. Que yo sepa, python3
está disponible en todas las versiones de Ubuntu 16.04 y superiores.
- Si todos sus hosts definitivamente lo tienen
python3
, puede agregar la variable a su group_vars/all.yml
(o equivalente):
# group_vars/all.yml
ansible_python_interpreter: /usr/bin/python3
- Si algunos de sus hosts no lo tienen
python3
y tiene una forma de etiquetarlos cuando usa un inventario dinámico (por ejemplo, etiquetado de AWS ec2.py
), puede aplicar la variable a ciertos hosts como este:
# group_vars/tag_OS_ubuntu1804.yml
ansible_python_interpreter: /usr/bin/python3
- Si usa un inventario estático y puede agrupar hosts en función de si tienen
python3
, podría hacer algo como esto:
# inventory/hosts
[python2_hosts]
centos7_server
[python3_hosts]
u1804_server
[python3_hosts:vars]
ansible_python_interpreter=/usr/bin/python3
Esta opción me gusta más porque no requiere cambios en el host remoto y solo cambios menores en las variables, a diferencia de las opciones 2 y 3, que requieren adiciones a cada libro de jugadas.
Opción 2: instalar Python 2 usando raw
Esta opción requiere poner una jugada en la parte superior de cada libro de jugadas con la gather_facts: false
que se raw
instala python
:
- name: install python2 on all instances
hosts: "*"
gather_facts: false
tasks:
- name: run apt-get update and install python
raw: "{{ item }}"
loop:
- sudo apt-get update
- sudo apt-get -y install python
become: true
ignore_errors: true
ignore_errors: true
es necesario si planea ejecutar la reproducción en hosts que no se han apt-get
instalado (por ejemplo, cualquier cosa basada en RHEL), de lo contrario, se producirá un error en la primera reproducción.
Esta solución funciona, pero es la más baja en mi lista por varias razones:
- Debe ir al principio de cada libro de jugadas (en oposición a la opción 1)
- Asume que
apt
está en el sistema e ignora los errores (a diferencia de la opción 3)
apt-get
los comandos son lentos (a diferencia de la opción 3)
Opción 3: enlace simbólico /usr/bin/python -> /usr/bin/python3
utilizandoraw
No he visto esta solución propuesta por nadie más. No es ideal, pero creo que es superior a la opción 2 en muchos sentidos. Mi sugerencia es utilizar raw
para ejecutar un comando de shell para enlace simbólico /usr/bin/python -> /usr/bin/python3
si python3
está en el sistema y python
no es:
- name: symlink /usr/bin/python -> /usr/bin/python3
hosts: "*"
gather_facts: false
tasks:
- name: symlink /usr/bin/python -> /usr/bin/python3
raw: |
if [ -f /usr/bin/python3 ] && [ ! -f /usr/bin/python ]; then
ln --symbolic /usr/bin/python3 /usr/bin/python;
fi
become: true
Esta solución es similar a la opción 2 en que necesitamos ponerla en la parte superior de cada libro de jugadas, pero creo que es superior en algunos aspectos:
- Solo crea el enlace simbólico en el caso específico que
python3
está presente y python
no lo está: no anulará Python 2 si ya está instalado
- No asume que
apt
está instalado
- Puede ejecutarse contra todos los hosts sin ningún manejo especial de errores
- Es súper rápido en comparación con cualquier cosa con
apt-get
Obviamente, si necesita instalar Python 2 en /usr/bin/python
, esta solución es una opción prohibida y la opción 2 es mejor.
Conclusión
- Sugiero usar la opción 1 en todos los casos si puedes.
- Sugiero usar la opción 3 si su inventario es realmente grande / complejo y no tiene forma de agrupar hosts fácilmente
python3
, lo que hace que la opción 1 sea mucho más difícil y propensa a errores.
- Solo sugiero la opción 2 sobre la opción 3 si necesita instalar Python 2 en
/usr/bin/python
.
Fuentes