Ansibleは/ bin / sh:1で失敗する:/ usr / bin / python:not found


187

今まで見たことのないエラーが発生しています。コマンドとエラーは次のとおりです。

$ 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

これがcreate_api.ymlファイルです。

---

- hosts: api
  remote_user: root
  roles:
    - api

そしてここにhostsファイルがあります:

[api]
104.55.47.224

役割セクションを削除すると、最初のタスクに到達しません。代わりに、行に到達するだけになります/bin/sh: 1: /usr/bin/python: not found。ここで何が起こっているのでしょうか?


注:誰かがIPアドレスにpingを実行しても応答が得られない場合は、コードを貼り付けてからIPアドレスを変更したことを知っておく必要があります。

編集 pythonがローカルにインストールされましたが、問題は、Ubuntu 15.04を実行しているリモートマシンにインストールされなかったことです。

回答:


171

Python 3.4.3同梱されansibleにはPython 2が必要であるため、Ubuntu 15.10サーバーでansibleを実行しているこのエラーに遭遇しました。

これが私のprovision.yml外見です。

- 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
  • apt-getで-y(すべての質問に対してyesと言う)オプションを忘れないでください(またはrawモジュールが黙ってスタックします)

  • gather_facts: no 行も重要です(Pythonがないとファクトを収集できないため)


12
それでは、後続のロールはファクトを使用できません...ファクトを再度収集する方法はありますか?aha、stackoverflow.com
questions /

16
「gather_facts:no」行重要であることに注意してください。
rcreswick

6
@ surfer190素晴らしい発見!action: setup最後のpre_taskとして追加することもうまくいったこともわかりました:)
mrooney

1
@ surfer190 ansibleでEC2を使用している場合、ここで私の回答を参照してください。CloudInitを使用してpython2をインストールし、ファクトの収集を通常どおり使用できます。
Miroslav、

1
誰かが疑問に思っている場合でも、Python 2をにインストールするためにタスクを実行する必要はありません。レギュラーもうまくいきます。ただし、Ansible モジュールを呼び出す別のtoタスクを使用してそれをに配置すると、ホストに割り当てられたすべてのロールでファクトを使用できるようになります。rawpre_taskstaskspre_taskssetup
ケニーエビット2017

125

Ansible 2.2は、Python 3サポートの技術プレビューを備えています。これを利用するには(Ubuntu 16.04にPython 2をインストールする必要がないため)、ansible_python_interpreter設定オプションをに設定します/usr/bin/python3。これは、インベントリファイルでホストごとに実行できます。

[db]
123.123.123.123 ansible_python_interpreter=/usr/bin/python3

この変数に/ usr / bin / pythonを追加しようとしましたが、機能しませんでした。代わりにpython3を追加すると機能し、この問題は修正されました
Deep LF

97

解決策1:

を使用Ansible >2.2.0している場合は、ansible_python_interpreter構成オプションを/usr/bin/python3次のように設定できます。

ansible my_ubuntu_host -m ping -e 'ansible_python_interpreter=/usr/bin/python3'

またはインベントリファイル:

[ubuntu_hosts]
<xxx.xxx.xxx.xxx>

[ubuntu_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

解決策2:

使用しているAnsible <2.2.0場合は、これらpre_tasksをプレイブックに追加できます。

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

UPDATEを 使用するとansible 2.8.x、心配する必要はありません。コントローラとターゲットマシンの両方で、Python> 3.5の場合はそのままで機能します。


タグを使用してプレイブックを実行する場合は、必ずタグを追加してください。常にセットアップタスクに追加してください。そうしないと、タグを使用しているときにansibleがファクトを収集しません。
Ionut Bajescu

16
私は持っansible 2.3.0.0ていますが、そのままでは機能しません。OPによって投稿されたものと同じエラー。
コーダー、2017年

これが明確でない場合は、これをインクルード変数ではなくホストインベントリファイルに追加する必要があります。つまり、ホストアドレス/名前と同じインベントリファイルにあります。
Shawn Mehan 2017

32

rawモジュールを使用して、リモートホストにPythonをインストールできます。

- raw: sudo apt-get install python-simplejson

11
これがあなたの役割のタスクの前、そしてメタファイルの依存関係の前に呼び出されることを確認するには、次のようにプレイブックに追加します:pre_tasks: - raw: sudo apt-get install python-simplejson
Laurens Rietveld

5
プレイブックでは、gather_facts 無効にする必要があります。無効にしないと、rawコマンドを実行する前に失敗します。(gather_facts:no)
rcreswick

@rcreswickそれは私の問題であり、あなたの解決策は私のために働いた。本当にありがとう。私はメインの.ymlファイル(setup-ansible.yml)に "gather_facts:no"行を入れ、次のコマンドでプレイブックを実行しました: "ansible-playbook -i hosts setup-ansible.yml --flush-cache -vvvvvv -kK 」デフォルトのubuntuインストールでは「sudo」を実行するためにパスワードが必要なため、ansible-playbookで「-kK」オプションを使用しました。
Ali Yousefi Sabzevar

なぜpytghonではなくsimplejsonをインストールしているのに、pythonのインストールについて話しているのですか?
Henning

@Henning python-simplejsonはPythonで記述されているため、Pythonが必要です。simplejsonは、ほとんどのAnsibleコアモジュールの要件でもあります。インストールすることpython-simplejsonによってapt-get/ yumあなたは...また、Pythonのインストール、したがって、すべての基本的なAnsibleの依存関係をカバー
udondan

18

他のすべての人の答えを要約するために、ここに私のために働いた組み合わせた設定があります:

 - 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

14

私は個人的に、この問題に対する3つの可能な解決策を見つけました。

オプション1- デフォルトでインストールされansible_python_interpreter: /usr/bin/python3python3いるホストに設定

python3デフォルトでインストールされているかどうかによってホストをグループ化する方法がある場合、これは問題を解決するための優れた方法だと思います。私の知る限り、python3はUbuntuのすべてのリリース16.04 以降で使用できます。

  • すべてのホストに確実にがpython3ある場合、変数をgroup_vars/all.yml(または同等のもの)に追加できます。
# group_vars/all.yml

ansible_python_interpreter: /usr/bin/python3
  • 一部のホストになくpython3、動的インベントリを使用するときにそれらにタグを付ける方法がある場合(例:のAWSタグ付けec2.py)、次のように特定のホストに変数を適用できます。
# group_vars/tag_OS_ubuntu1804.yml

ansible_python_interpreter: /usr/bin/python3
  • 静的インベントリを使用していてpython3、ホストがあるかどうかに基づいてホストをグループ化できる場合は、次のようなことができます。
# inventory/hosts

[python2_hosts]
centos7_server

[python3_hosts]
u1804_server

[python3_hosts:vars]
ansible_python_interpreter=/usr/bin/python3

すべてのプレイブックに追加が必要なオプション2と3とは対照的に、リモートホストでの変更は必要なく、変数への小さな変更のみが必要なため、このオプションが最も好きです。

オプション2-を使用してPython 2をインストールする raw

このオプションでは、とのすべての脚本の上部に遊びを置く必要がありgather_facts: false、その用途rawをインストールするには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: trueapt-getインストールされていないホスト(RHELベースなど)でプレイを実行する場合は必須です。それ以外の場合は、最初のプレイでエラーになります。

このソリューションは機能しますが、いくつかの理由で私のリストの中で最も低いものです。

  1. すべてのプレイブックの一番上に移動する必要があります(オプション1ではなく)
  2. aptシステム上にあると想定し、エラーを無視します(オプション3ではなく)
  3. apt-get コマンドが遅い(オプション3とは対照的)

オプション3-Symlink /usr/bin/python -> /usr/bin/python3usingraw

このソリューションが他の人から提案されたのを見たことがありません。これは理想的ではありませんが、オプション2よりも多くの点で優れていると思います。私の提案は使用することですrawシンボリックリンクにシェルコマンドを実行する/usr/bin/python -> /usr/bin/python3場合はpython3、システムにある pythonではありません。

- 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

このソリューションは、すべてのプレイブックの一番上に配置する必要があるという点でオプション2に似ていますが、いくつかの点で優れていると思います。

  • python3存在しpythonていない特定のケースでのみシンボリックリンクを作成します-すでにインストールされている場合、Python 2をオーバーライドしません
  • aptインストールされているとは想定していません
  • 特別なエラー処理なしですべてのホストに対して実行できます
  • と比べて超高速です apt-get

明らかにPython 2をにインストールする必要がある場合/usr/bin/python、このソリューションはノーゴーであり、オプション2の方が優れています。

結論

  • 可能であれば、すべての場合にオプション1を使用することをお勧めします
  • インベントリが非常に大きく複雑で、でホストを簡単にグループ化する方法がない場合は、オプション3を使用することをお勧めします。これによりpython3オプション1ははるかに困難でエラーが発生しやすくなります。
  • にPython 2をインストールする必要がある場合にのみ、オプション3よりオプション2をお勧めします/usr/bin/python

出典


13

Ansibleを実行するには、Python 2.7が必要です。Ubuntu 16.04では、次のコマンドでインストールできます。

sudo apt-get install python-minimal

その後、私は走ることができました

ansible-playbook -i inventories/staging playbook.yml

ansibleを正常に実行します

Ubuntu 16.04でのansibleの使用で詳細を確認してください


12

私がこれをubuntu 15.10で新しい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

新しいOVH SSD上のubuntu 16.04の場合、python2パッケージが利用可能になる前に、apt-getアップグレードを行う必要がありました。


8

1つのプレイブックに実際に複数のプレイがある可能性があることがわかりました。そのため、私のセットアップには、すべてのホストで実行される「依存関係プロビジョニング」プレイと、特定のホスト用の他のプレイが含まれています。だからもうpre_tasks

例えば:

- 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
  # ....

6

他の人が言ったように、これはpython2がないためです。ここでの他の回答は、pre_tasksおよびgather_facts: noで回避策を提供しますが、EC2を使用していて、インスタンスをansibleで起動する場合は、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

その後、人々は通常、次のようにsshが利用可能になるのを待ちます:

  - 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

ただし、CloudInitは起動プロセスのかなり遅い段階で実行されるため、これが常に十分な長さであるとは限らないため、sshが使用可能になった直後にpython2がまだインストールされていない可能性があります。したがって、インスタンスが作成されたばかりの場合に備えて、一時停止を追加しました。

  - name: "Wait for cloud init on first boot"
    pause: minutes=2
    when: ec2|changed

これは完全に機能し、利点として、実行ごとにpython2をチェックせず、後で事実を収集するための回避策を実行する必要がありません。

他のクラウドプロバイダーも同様のCloudInit機能を提供していると思いますので、ユースケースに合わせてください。


3

パッカーを使用している人は以下の解決策が役立つかもしれません

あなたがpackerのansibleプロビジョナーを使用していると仮定しましょう、あなたの設定は以下のようになるでしょう

最初にシェルプロビジョニングを使用してpythonをインストールしてから、以下に示すようにansible_python_intepreterオプションを設定できます。

"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"
      ]
    },

2

デフォルトでは、AnsibleにはPython 2が必要ですが、Ansible 2.2以降はPython 3でも動作します。

したがって、rawモジュールを使用してPython 2をインストールするか、たとえば

ansible localhost --sudo -m raw -a "yum install -y python2 python-simplejson"

または、次のように、インベントリファイルにansible_python_interpreter変数を設定します

[local]
localhost ansible_python_interpreter="env python3"

Dockerの場合、次の行を追加できます。

RUN printf '[local]\r\nlocalhost ansible_python_interpreter="env python3"\r\n' > /etc/ansible/hosts

または次のように実行します。

ansible-playbook /ansible/provision.yml -e 'ansible_python_interpreter=/usr/bin/python3' -c local

1

この要旨によれば、次のようにしてUbuntu 16.04にPython2をインストールできます。

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.

1

たくさんの答え..私もこのページから始めたので投稿してくれてありがとう!

私は少し掘り下げましたが、Ubuntu 14.04LTSでしっかりしていて、Ubuntu 15.04LTSは最新のものを落としているように見え、Ubuntu 16.04LTS pythonは落ちているようaptitudeです。

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

become他の場所で管理している場合は、自由に削除してください。

出典:


1

ターゲットマシン、つまりSSH接続先のマシンにPythonをインストールすることで、同じ問題を修正することができました。私は次のコマンドを使用していました:

sudo apt-get install python-minimal

1

@Miroslav、正しい方向に向けてくれてありがとう。で使用user_dataしたec2_instanceもモジュールでそれは御馳走のように機能します。

すなわち

- 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     

1

の最優先事項としてpython3を使用することをUbuntu 18.04に指示できます/usr/bin/python

- hosts: all
  become: true
  pre_tasks:
    - raw: update-alternatives --install /usr/bin/python python /usr/bin/python3 1

0

自分のローカルマシンだけでなく、リモートホストにもpythonをインストールする必要があることに気づくまで、私は同じ問題を抱えていました。今ではうまくいきます!


-2

これに遭遇しました。

ubuntu 16.04はvagrantにデプロイするので、vagrantを使用していない場合、私のコメントは無意味です。

次の迷惑プラグイン(トリガー、シェルコマンダ)をインストールし、マシンにpython 2.7.6(チオースプラグインがないわけではありません)をインストールしました。

これが最後のテストでした。それ以外の場合は、このインストールをVagrantファイルのシェルコマンドに含めようとしていました。

それが誰かを助けることを願っています


2
Ansibleを使用している場合、以下のAnsibleソリューションが正しい修正です。一部のプラグインの副作用が問題を要求しているように見えるため、Vagrantが誤ってVagrantをインストールすることを期待しています。
Paul Becotte

すみませんが、pythonがない場合にansible pretaskを実行するにはどうすればよいですか?私は解決策を試してみましたが、タスクの設定で失敗するため、前のタスクの前にイベントが発生しました。vagrantファイル内のvagrantシェルコマンドは、(もちろんvagrantの場合は)これを行うための最良の方法ですが、開発者にインストールしたvagrantプラグインがその役割を果たしていることに気づきました。私はプラグインに依存していませんが、vagrantファイルに依存しています。プラグインでも動作することを指摘しましたが、vagrantファイルの方が(自動化のためにも)良い選択です。手動で何もする必要がないためです。 destroy / provision
wadoo

1
そのコードブロックをそのままコピーしましたが、回答を投稿する直前に説明どおりに機能しました。私はあなたがおそらくgather_facts: nopythonを必要とする行を入れなかったと思います。他の可能性としては、ホストマシンにもpythonが必要ですが、プロセスの早い段階でエラーが発生したと思います。
Paul Becotte

私もペーストをコピーしましたが、それは仕事で金曜日の夜でした。正直に、gather_factパートを取ったかどうか思い出せません。とにかく、今朝もう一度別のコンピューターで実行した場合、コマンドをvagrantfileに入れただけで、実サーバーでの運用に入るまでは十分です。フレッシュな心でもう一度テストします(金曜日の夜ではないので)答え;)
wadoo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.