[Dockerハンズオン]Ansibleはpythonがないと実行できないのか
Ansibleはエージェントレスで実行できますが、ターゲットノードにはpythonは必要とのことです。
それは本当なのか、ということをDocker上で試してみます。
コードは、Gitにあります。
構成
Ansibleをインストールしたマスターノード(ubuntu)が、CentOSとUbuntuとpythonをアンインストールしたubuntuを動かします。
なお、pythonを持っていないubuntuは実行に失敗します。
ubuntuはパッケージマネージャーにAptを使っており、Aptはpythonに依存していないので、pythonを消すことができます。
実行方法
1 |
docker-compose up -d |
2. Ansibleコンテナに接続
1 |
docker exec -it ansible /bin/bash |
3. targetに対し、sshの接続確認
1. centos, ubuntu への接続
1 2 3 4 5 6 7 8 9 10 11 |
ssh target-centos # yesで接続 exit ssh target-ubuntu # yesで接続 root # loginパスワード:rootを入力(設定方法は後述) python3 -V # pythonのバージョンが表示されることを確認 exit |
2. ubuntu without python への接続
1 2 3 4 5 6 7 |
ssh target-no-python-ubuntu # yesで接続 root # loginパスワード:rootを入力(設定方法は後述) python3 -V # pythonが入っていないことを確認 exit |
4. target nodeに対し、ansibleコマンドを実行
1 2 3 4 5 6 7 |
ansible-playbook -i inventry.ini playbook.yml --ask-vault-pass -e @vaulted_vars.yaml # vaultファイルの復号パスワードを聞くように設定しています。 # -e @<filename> とすることで、変数ファイルを渡すことができます。 pass # Vault password: pass を入力します。 |
5. 実行ログの確認(pythonがないUbuntuのみ失敗する)
9行目のログの通り、pythonがないUbuntuは実行に失敗しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
root@e03b1b5dae16:/var/data# ansible-playbook -i inventry.ini playbook.yml --ask-vault-pass -e @vaulted_vars.yaml Vault password: PLAY [targets] **************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************** fatal: [target-no-python-ubuntu]: FAILED! => {"ansible_facts": {}, "changed": false, "failed_modules": {"setup": {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "failed": true, "module_stderr": "Shared connection to target-no-python-ubuntu closed.\r\n", "module_stdout": "/bin/sh: 1: /usr/bin/python: not found\r\n", "msg": "The module failed to execute correctly, you probably need to set the interpreter.\nSee stdout/stderr for the exact error", "rc": 127, "warnings": ["No python interpreters found for host target-no-python-ubuntu (tried ['/usr/bin/python', 'python3.7', 'python3.6', 'python3.5', 'python2.7', 'python2.6', '/usr/libexec/platform-python', '/usr/bin/python3', 'python'])"]}}, "msg": "The following modules failed to execute: setup\n"} ok: [target-ubuntu] ok: [target-centos] TASK [targets test] *********************************************************************************************************************************************** [WARNING]: Consider using the file module with state=touch rather than running 'touch'. If you need to use command because file is insufficient you can add 'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message. changed: [target-ubuntu] changed: [target-centos] PLAY [centos] ***************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************** ok: [target-centos] TASK [centos test] ************************************************************************************************************************************************ changed: [target-centos] PLAY [ubuntu] ***************************************************************************************************************************************************** TASK [Gathering Facts] ******************************************************************************************************************************************** ok: [target-ubuntu] TASK [ubuntu test] ************************************************************************************************************************************************ changed: [target-ubuntu] PLAY RECAP ******************************************************************************************************************************************************** target-centos : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 target-no-python-ubuntu : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0 target-ubuntu : ok=4 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 |
6. target-centos, target-ubuntuに再接続し、targets, centos, ubuntu ファイルが追加されていることを確認
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ssh target-centos ls # targets, centosファイルができる exit ssh target-ubuntu root # enter password ls # targets, ubuntuファイルができる exit |
Ansibleの解説
Inventryファイルについて
1 2 3 4 5 6 7 8 9 10 |
[targets:children] centos ubuntu [centos] target-centos [ubuntu] target-ubuntu ansible_ssh_pass='{{ ubuntu_pass }}' target-no-python-ubuntu ansible_ssh_pass='{{ np_ubuntu_pass }}'こ |
構成はこのように入れ子構造になっています。
Playbookについて
先ほど入れ子構造にしたそれぞれに対して(targetsとcentosとubuntu)ファイルを作っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
- hosts: targets tasks: - name: "targets test" shell: | touch targets - hosts: centos tasks: - name: "centos test" shell: | touch centos - hosts: ubuntu tasks: - name: "ubuntu test" shell: | touch ubuntu |
なぜpythonがないと失敗するのか
Ansibleがインストールされたマスターノードは、実行時に、実行対象のコントロールノードに対して、pythonの実行ファイルを渡しています。
なのでpythonがないコントロールノードは実行に失敗します。
pythonをインストールできないネットワーク機器などでAnsibleを使う際には注意です。
まとめ
AnsibleをDockerを使って動かし、pythonがないと動かないことを確認しました。
Ansible vaultを使った暗号化についてはこちら。