Ich bin auf einen Fehler gestoßen, den ich noch nie gesehen habe. Hier ist der Befehl und der Fehler:
$ 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
Hier ist die Datei create_api.yml:
---
- hosts: api
remote_user: root
roles:
- api
Und hier ist die hosts-Datei:
[api]
104.55.47.224
Ich kann den Rollenabschnitt entfernen und er wird es nicht bis zur ersten AUFGABE schaffen, stattdessen wird er es nur in die Zeile /bin/sh: 1: /usr/bin/python: not found
bringen. Was könnte hier los sein?
HINWEIS: Falls jemand die IP-Adresse anpingt und keine Antwort erhält, sollten Sie wissen, dass ich die IP-Adresse seit dem Einfügen des Codes geändert habe.
EDIT python wurde lokal installiert. Das Problem war, dass es nicht auf dem Remote-Computer installiert war, auf dem Ubuntu 15.04 ausgeführt wurde
Ich bin auf diesen Fehler gestoßen, der auf Ubuntu 15.10 -Server ausgeführt wird, da er mit Python 3.4.3 ausgeliefert wird und ansible Python 2 erfordert.
So sieht mein provision.yml
jetzt aus:
- 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
Vergiss nicht die Option -y (sagt ja zu allen Fragen) mit apt-get (oder das Rohmodul bleibt stumm)
gather_facts: no
line ist auch kritisch (da wir ohne Python keine Fakten sammeln können)
Ansible 2.2 bietet eine technische Vorschau der Python 3-Unterstützung. Um dies zu nutzen (damit Sie Python 2 nicht auf Ubuntu 16.04 installieren müssen), setzen Sie die Option ansible_python_interpreter
config auf /usr/bin/python3
. Dies kann pro Host in Ihrer Inventardatei erfolgen:
[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3
Lösung 1:
Wenn Sie Ansible >2.2.0
verwenden, können Sie die Konfigurationsoption ansible_python_interpreter
auf /usr/bin/python3
setzen:
ansible my_ubuntu_Host -m ping -e 'ansible_python_interpreter=/usr/bin/python3'
oder in Ihrer Inventardatei:
[ubuntu_hosts]
<xxx.xxx.xxx.xxx>
[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3
Lösung 2:
Wenn Sie Ansible <2.2.0
verwenden, können Sie diese pre_tasks
zu Ihrem Playbook hinzufügen:
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
Sie können das Modul raw verwenden, um Python auf den Remote-Hosts zu installieren:
- raw: Sudo apt-get install python-simplejson
Um die Antworten aller anderen zusammenzufassen, hier die kombinierten Einstellungen, die für mich funktioniert haben
- 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
Sie benötigen Python 2.7, um Ansible auszuführen. Unter Ubuntu 16.04 können Sie es mit diesem Befehl installieren:
Sudo apt-get install python-minimal
Danach konnte ich rennen
ansible-playbook -i inventories/staging playbook.yml
Bitte überprüfen Sie mehr unter Using ansible auf Ubuntu 16.04 .
Ich persönlich habe 3 mögliche Lösungen für dieses Problem gefunden, die in verschiedenen Situationen gut funktionieren:
ansible_python_interpreter: /usr/bin/python3
Für Hosts ein, auf denen standardmäßig python3
Installiert istIch denke, dies ist die beste Methode, um das Problem zu lösen, wenn Sie die Möglichkeit haben, Ihre Hosts danach zu gruppieren, ob standardmäßig python3
Installiert ist oder nicht. Soweit mir bekannt ist, ist python3
Auf allen Ubuntu-Releases 16.04 und höher verfügbar.
python3
Haben, können Sie die Variable zu Ihrem group_vars/all.yml
(Oder einem gleichwertigen Wert) hinzufügen:# group_vars/all.yml
ansible_python_interpreter: /usr/bin/python3
python3
Verfügen und Sie diese mithilfe des dynamischen Inventars mit Tags versehen können (z. B. AWS-Tagging für ec2.py
), Können Sie die Variable auf bestimmte Hosts wie diesen anwenden :# group_vars/tag_OS_ubuntu1804.yml
ansible_python_interpreter: /usr/bin/python3
python3
Gruppieren können, können Sie Folgendes tun:# inventory/hosts
[python2_hosts]
centos7_server
[python3_hosts]
u1804_server
[python3_hosts:vars]
ansible_python_interpreter=/usr/bin/python3
Ich mag diese Option am meisten, weil sie keine Änderungen auf dem Remote-Host und nur geringfügige Änderungen an Variablen erfordert, im Gegensatz zu den Optionen 2 und 3, die Ergänzungen zu jedem Playbook erfordern.
raw
Diese Option setzt voraus, dass jedes Playbook mit gather_facts: false
, Das raw
verwendet, um python
zu installieren, oben mit einem Stück versehen wird:
- 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
Ist erforderlich, wenn Sie das Spiel auf Hosts ausführen möchten, auf denen apt-get
Nicht installiert ist (z. B. auf RHEL-Basis). Andernfalls treten Fehler beim ersten Spiel auf.
Diese Lösung funktioniert, ist jedoch aus folgenden Gründen die niedrigste auf meiner Liste:
apt
befindet sich im System und ignoriert Fehler (im Gegensatz zu Option 3)apt-get
- Befehle sind langsam (im Gegensatz zu Option 3)/usr/bin/python -> /usr/bin/python3
Mit raw
Ich habe diese von niemandem vorgeschlagene Lösung gesehen. Es ist nicht ideal, aber ich denke, es ist Option 2 in vielerlei Hinsicht überlegen. Mein Vorschlag ist, raw
zu verwenden, um einen Shell-Befehl zum Verknüpfen von /usr/bin/python -> /usr/bin/python3
Auszuführen, wenn python3
Auf dem System vorhanden ist ndpython
nicht:
- 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
Diese Lösung ist ähnlich wie Option 2, da wir sie an die Spitze jedes Spielbuchs setzen müssen, aber ich denke, dass sie in einigen Punkten überlegen ist:
python3
Vorhanden ist und python
nicht - es wird Python 2 nicht überschrieben, wenn es bereits installiert istapt
installiert istapt-get
Wenn Sie brauchen Python 2 bei /usr/bin/python
Installiert haben, ist diese Lösung ein No-Go und Option 2 ist besser.
python3
Einfach zu gruppieren, was Option 1 viel schwieriger macht und fehleranfällig./usr/bin/python
Installiert haben müssen.Was ich früher auf Ubuntu 15.10 an einem frischen Digital-Ocean-Tropfen gearbeitet habe:
# 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
Für Ubuntu 16.04 auf einer neuen OVH-SSD musste ich apt-get upgraden, bevor die python2-Pakete verfügbar waren.
Ich habe herausgefunden, dass es tatsächlich möglich ist, mehrere Spiele in einem einzigen Spielbuch zu haben. Daher enthält mein Setup jetzt ein "Abhängigkeitsbereitstellung", das auf allen Hosts läuft, und andere Spiele für bestimmte Hosts. Also kein pre_tasks
mehr.
Zum Beispiel:
- 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
# ....
Wie andere sagten, liegt dies an fehlendem Python2. Andere Antworten hier bieten eine Problemumgehung mit pre_tasks
und gather_facts: no
. Wenn Sie jedoch mit EC2 arbeiten und die Instanz mit ansible starten, können Sie die user_data
-Option verwenden:
- 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
Dann warten die Leute normalerweise darauf, dass ssh so verfügbar ist:
- 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
Ich habe jedoch festgestellt, dass dies nicht immer lange genug ist, da CloudInit ziemlich spät im Bootvorgang ausgeführt wird, sodass der Python2 möglicherweise nicht direkt installiert wird, nachdem ssh verfügbar ist. Ich habe also eine Pause hinzugefügt, falls die Instanz gerade erstellt wurde:
- name: "Wait for cloud init on first boot"
pause: minutes=2
when: ec2|changed
Dies erledigt die Aufgabe perfekt, und als Vorteil wird nicht bei jedem Durchlauf nach Python2 gesucht, und Sie müssen keine Problemumgehungen durchführen, um später Informationen zu sammeln.
Ich bin sicher, dass andere Cloud-Anbieter eine ähnliche CloudInit-Funktionalität bieten, passen Sie sich also an Ihren Anwendungsfall an.
@Miroslav, danke, dass du mich in die richtige Richtung zeigst. Ich habe auch user_data
im ec2_instance
-Modul verwendet und es funktioniert wie ein Genuss.
Das heißt.
- 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
Ich konnte das gleiche Problem beheben, indem ich Python auf dem Zielrechner installierte, d. H. Dem Rechner, auf den wir SSH wollen. Ich hatte folgenden Befehl verwendet:
Sudo apt-get install python-minimal
Viele Antworten .. Danke fürs Posting, da ich auch von dieser Seite angefangen habe!
Ich grub ein bisschen und es war solide mit Ubuntu 14.04LTS, Ubuntu 15.04LTS schien den neuesten python
gelöscht zu haben, und Ubuntu 16.04LTS schien aptitude
fallen zu lassen.
Ich füge die folgende Aktion in meinen Bootstrap ein, bevor ich apt
aufrufe:
- 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
Wenn Sie become
an anderer Stelle verwalten, können Sie es entfernen.
Quellen:
Nach this Gist können Sie Python2 auf Ubuntu 16.04 wie folgt installieren:
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.
Standardmäßig benötigt Ansible Python 2 , jedoch kann Ansible 2.2+ auch mit Python 3 funktionieren.
Installieren Sie entweder Python 2 mithilfe des Moduls raw
, z.
ansible localhost --Sudo -m raw -a "yum install -y python2 python-simplejson"
oder setze ansible_python_interpreter
variable in der Inventardatei wie:
[local]
localhost ansible_python_interpreter="env python3"
Für Docker können Sie folgende Zeile hinzufügen:
RUN printf '[local]\r\nlocalhost ansible_python_interpreter="env python3"\r\n' > /etc/ansible/hosts
oder führe es als:
ansible-playbook /ansible/provision.yml -e 'ansible_python_interpreter=/usr/bin/python3' -c local
Für Benutzer, die Packer verwenden, ist die folgende Lösung möglicherweise hilfreich
nehmen wir an, Sie verwenden einen ansible provisioner of packer. Ihre Konfiguration könnte wie folgt aussehen
sie können Python zuerst mit Shell Provisioner installieren und dann die Option ansible_python_intepreter wie unten gezeigt konfigurieren
"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"
]
},
Sie können Ubuntu 18.04 mitteilen, dass Sie Python3 als erste Priorität für /usr/bin/python
verwenden möchten.
- hosts: all
become: true
pre_tasks:
- raw: update-alternatives --install /usr/bin/python python /usr/bin/python3 1
Ich hatte das gleiche Problem, bis mir klar wurde, dass Sie Python sowohl auf dem Remote-Host als auch auf Ihrem eigenen lokalen Computer installieren müssen. jetzt gehts!