tower - Ansible falla con/bin/sh: 1:/usr/bin/python: no encontrado
ansible vars (19)
@Miroslav, gracias por señalarme en la dirección correcta.
También utilicé
user_data
en el módulo
ec2_instance
y funciona como un regalo.
Es decir
- name: Creating single EC2 instance
ec2_instance:
region: "{{ aws_region }}"
key_name: "{{ aws_ec2_key_pair }}"
name: "some-cool-name"
instance_type: t1.micro
image_id: ami-d38a4ab1
security_group: sg-123456
vpc_subnet_id: sn-678901234
network:
assign_public_ip: no
volumes:
- device_name: /dev/sda1
ebs:
volume_type: gp2
volume_size: 15
user_data: |
#!/bin/bash
#
apt update
apt install -y python-simplejson
termination_protection: yes
wait: yes
Me encuentro con un error que nunca había visto antes. Aquí está el comando y el error:
$ ansible-playbook create_api.yml
PLAY [straw] ******************************************************************
GATHERING FACTS ***************************************************************
failed: [104.55.47.224] => {"failed": true, "parsed": false}
/bin/sh: 1: /usr/bin/python: not found
TASK: [typical | install required system packages] *****************************
FATAL: no hosts matched or all hosts have already failed -- aborting
PLAY RECAP ********************************************************************
to retry, use: --limit @/Users/john/create_api.retry
104.55.47.224 : ok=0 changed=0 unreachable=0 failed=1
Aquí está el archivo create_api.yml:
---
- hosts: api
remote_user: root
roles:
- api
Y aquí está el archivo de hosts:
[api]
104.55.47.224
Puedo eliminar la sección de roles y no llegará a la primera TAREA, sino que solo llegará a la línea
/bin/sh: 1: /usr/bin/python: not found
.
¿Qué podría estar pasando aquí?
NOTA: En caso de que alguien haga ping a la dirección IP y no pueda obtener una respuesta, debe saber que he cambiado la dirección IP desde que pegué el código.
EDITAR Python se instaló localmente, el problema era que no estaba instalado en la máquina remota, que ejecutaba Ubuntu 15.04
Ansible 2.2 presenta una vista previa técnica del soporte de Python 3.
Para aprovechar esto
(para que no tenga que instalar Python 2 en Ubuntu 16.04), simplemente configure la opción de configuración
ansible_python_interpreter
en
/usr/bin/python3
.
Esto se puede hacer por host en su archivo de inventario:
[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3
Como otros dijeron, esto se debe a la falta de python2.
Otras respuestas aquí proporcionan una solución alternativa con
pre_tasks
y
gather_facts: no
, sin embargo, si está en EC2 y
gather_facts: no
la instancia con ansible, puede usar la opción
user_data
:
- ec2:
key_name: mykey
instance_type: t2.micro
image: ami-123456
wait: yes
group: webserver
count: 3
vpc_subnet_id: subnet-29e63245
assign_public_ip: yes
user_data: |
#!/bin/bash
apt-get update
apt-get install -y python-simplejson
register: ec2
Entonces la gente generalmente espera que ssh esté disponible de esta manera:
- name: "Wait for the instances to boot and start ssh"
wait_for:
host: "{{item.public_ip}}"
port: 22
delay: 5
timeout: 300
with_items: "{{ ec2.tagged_instances }}"
when: ec2|changed
Sin embargo, he descubierto que esto no siempre es suficiente, ya que CloudInit se ejecuta bastante tarde en el proceso de arranque, por lo que Python2 podría no instalarse justo después de que ssh esté disponible. Así que he agregado una pausa en caso de que la instancia se haya creado:
- name: "Wait for cloud init on first boot"
pause: minutes=2
when: ec2|changed
Esto hará el trabajo a la perfección y, como ventaja, no está buscando python2 en cada ejecución y no tiene que hacer ninguna solución para recopilar datos más adelante.
Estoy seguro de que otros proveedores de la nube ofrecen una funcionalidad similar de CloudInit, así que adáptese a su caso de uso.
De acuerdo con este Gist , puede instalar Python2 en Ubuntu 16.04 de la siguiente manera:
enter code here
gather_facts: False
pre_tasks:
- raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
- setup: # aka gather_facts
tasks:
# etc. etc.
De manera predeterminada, Ansible requiere Python 2 , sin embargo, Ansible 2.2+ también puede funcionar con Python 3 .
Entonces, instale Python 2 usando el
módulo sin
raw
, por ejemplo
ansible localhost --sudo -m raw -a "yum install -y python2 python-simplejson"
o establezca la
variable
ansible_python_interpreter
en el archivo de inventario, como:
[local]
localhost ansible_python_interpreter="env python3"
Para Docker, puede agregar la siguiente línea:
RUN printf ''[local]/r/nlocalhost ansible_python_interpreter="env python3"/r/n'' > /etc/ansible/hosts
o ejecutarlo como:
ansible-playbook /ansible/provision.yml -e ''ansible_python_interpreter=/usr/bin/python3'' -c local
Descubrí que en realidad es posible tener múltiples reproducciones en un solo libro de jugadas, por lo que mi configuración ahora contiene una reproducción de "aprovisionamiento de dependencias" que se ejecuta en todos los hosts y otras jugadas para hosts específicos.
Entonces no más
pre_tasks
.
Por ejemplo:
- name: dependency provisioning
hosts: all
become: yes
become_method: sudo
gather_facts: false
tasks:
- name: install python2
raw: sudo apt-get -y install python-simplejson
- name: production
hosts: production_host
roles:
- nginx
tasks:
- name: update apt cache
apt: update_cache=yes cache_valid_time=3600
# ....
- name: staging
hosts: staging_host
roles:
- nginx
tasks:
- name: update apt cache
apt: update_cache=yes cache_valid_time=3600
# ....
Lo que solía hacer que funcionara en ubuntu 15.10 en una nueva gota de Digital Ocean:
# my-playbook.yml
- name: python2
hosts: test
gather_facts: no
pre_tasks:
- raw: sudo apt-get -y install python-simplejson
$ ansible-playbook path/to/my-playbook.yml
Para ubuntu 16.04 en un SSD OVH nuevo, tuve que actualizar apt-get antes de que los paquetes python2 estuvieran disponibles.
Los que usan Packer pueden encontrar útil la siguiente solución
supongamos que usa el aprovisionador ansible de packer, su configuración puede verse a continuación
primero puede instalar python usando el aprovisionador de shell y luego configurar la opción ansible_python_intepreter como se muestra a continuación
"provisioners": [
{
"type": "shell",
"inline": [
"apk update && apk add --no-cache python python-dev ansible bash"
]
},
{
"type": "ansible-local",
"playbook_file": "playbooks/your-play-book.yml",
"playbook_dir": "playbooks",
"extra_arguments": [
"-e",
"''ansible_python_interpreter=/usr/bin/python3''",
"-vvv"
]
},
Me topé con este error al ejecutar ansible en el servidor Ubuntu 15.10 , porque se incluye con Python 3.4.3 y ansible requiere Python 2 .
Así es como
provision.yml
ve mi
provision.yml
ahora:
- hosts: my_app
sudo: yes
remote_user: root
gather_facts: no
pre_tasks:
- name: ''install python2''
raw: sudo apt-get -y install python
tasks:
- name: ''ensure user {{ project_name }} exists''
user: name={{ project_name }} state=present
-
No olvide la opción -y (dice sí a todas las preguntas) con apt-get (o el módulo sin procesar se atascará en silencio)
-
gather_facts: no
línea también es crítica (porque no podemos recopilar datos sin python)
Muchas respuestas ... ¡Gracias por publicar ya que empecé desde esta página también!
Hice un poco de excavación y fue sólido con Ubuntu 14.04LTS, Ubuntu 15.04LTS parecía haber caído la última
python
, y Ubuntu 16.04LTS parece haber caído en
aptitude
.
Pongo la siguiente acción en mi bootstrap antes de hacer cualquier llamada a
apt
:
- name: "FIX: Ubuntu 16.04 LTS doesn''t come with certain modules, required by ansible"
raw: apt-get install python-minimal aptitude -y
become: true
become_user: root
become_method: sudo
Si logras
become
otro lugar, no dudes en despojarlo.
Fuentes:
Necesita Python 2.7 para ejecutar Ansible. En Ubuntu 16.04, puede instalarlo mediante este comando:
sudo apt-get install python-minimal
Después de eso, podría correr
ansible-playbook -i inventories/staging playbook.yml
Por favor, consulte más en el uso de Ansible en Ubuntu 16.04
Nos topamos con esto.
Implementamos ubuntu 16.04 en un vagabundo, así que si no estás usando vagabundo, mi comentario no tiene sentido.
Instalamos los siguientes complementos vagabundos (trigger, shell-commander) y tenemos instalado Python 2.7.6 en la máquina (que no estaban exentos de complementos tioose) y después de que ansible se puede implementar
Era nuestra última prueba, de lo contrario, estábamos a punto de incluir esta instalación en un comando de shell en el archivo Vagrant
Espero que pueda ayudar a alguien
Para resumir las respuestas de todos los demás, aquí están las configuraciones combinadas que funcionaron para mí:
- hosts: all
become: true
gather_facts: false
# Ansible requires python2, which is not installed by default on Ubuntu Xenial
pre_tasks:
- raw: sudo apt-get -y install python-simplejson
# action: setup will gather facts after python2 has been installed
- action: setup
Personalmente encontré 3 posibles soluciones a este problema que funcionan bien en diferentes situaciones:
Opción 1:
ansible_python_interpreter: /usr/bin/python3
para los hosts que tienen
python3
instalado de forma predeterminada
Creo que este es el método superior para resolver el problema si tiene una forma de agrupar sus hosts si tienen o no
python3
instalado de forma predeterminada.
Que yo sepa,
python3
está disponible en todas las versiones de Ubuntu 16.04 y posteriores.
-
Si todos sus hosts definitivamente tienen
python3
, puede agregar la variable a sugroup_vars/all.yml
(o equivalente):
# group_vars/all.yml
ansible_python_interpreter: /usr/bin/python3
-
Si algunos de sus hosts no tienen
python3
y tiene una forma de etiquetarlos cuando usa el inventario dinámico (por ejemplo, etiquetado de AWS paraec2.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
, puede 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
gather_facts: false
que usa
raw
para instalar
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 tienen
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 algunas 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
comandos deapt-get
son lentos (a diferencia de la opción 3)
Opción 3 - Enlace simbólico
/usr/bin/python -> /usr/bin/python3
usando
raw
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 usar
raw
para ejecutar un comando de shell para vincular
/usr/bin/python -> /usr/bin/python3
si
python3
está en el sistema
y
python
no:
- 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 tenemos que 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 de que
python3
esté presente ypython
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 imposible 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 fácilmente hosts con
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
Pude solucionar el mismo problema instalando Python en la máquina de destino, es decir, la máquina a la que queremos SSH. Había usado el siguiente comando:
sudo apt-get install python-minimal
Puede indicarle a Ubuntu 18.04 que desea usar python3 como la primera prioridad para
/usr/bin/python
.
- hosts: all
become: true
pre_tasks:
- raw: update-alternatives --install /usr/bin/python python /usr/bin/python3 1
Puede usar el módulo sin procesar para instalar Python en los hosts remotos:
- raw: sudo apt-get install python-simplejson
Tuve el mismo problema, hasta que me di cuenta de que también necesita instalar Python en el host remoto, así como en su propia máquina local. ¡ahora funciona!
Solución 1:
Si usa
Ansible >2.2.0
, puede establecer la opción de configuración
ansible_python_interpreter
en
/usr/bin/python3
:
ansible my_ubuntu_host -m ping -e ''ansible_python_interpreter=/usr/bin/python3''
o en su archivo de inventario:
[ubuntu_hosts]
<xxx.xxx.xxx.xxx>
[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3
Solución 2:
Si está utilizando
Ansible <2.2.0
, puede agregar estas
pre_tasks
a su libro de jugadas:
gather_facts: False
pre_tasks:
- name: Install python for Ansible
raw: test -e /usr/bin/python || (apt -y update && apt install -y python-minimal)
register: output
changed_when: output.stdout != ""
tags: always
- setup: # aka gather_facts
ACTUALIZACIÓN
Con
ansible 2.8.x
, no necesita preocuparse por ello, está funcionando de forma
ansible 2.8.x
para python> 3.5 tanto para el controlador como para las máquinas de destino