My question is why can I not use a relative path to specify a bash script to run?
I have a ansible file structure following best practice.
My directory structure for this role is:
.
├── files
│ └── install-watchman.bash
└── tasks
└── main.yml
and the main.yml includes this:
- name: install Watchman
shell: "{{ role_path }}/files/install-watchman.bash"
- name: copy from files dir to target home dir
copy:
src: files/install-watchman.bash
dest: /home/vagrant/install-watchman.bash
owner: vagrant
group: vagrant
mode: 0744
- name: install Watchman
shell: files/install-watchman.bash
I would expect all three commands to work, but in practice the third one fails:
TASK [nodejs : install Watchman] ***********************************************
changed: [machine1]
TASK [nodejs : copy from files dir to target home dir] ********
changed: [machine1]
TASK [nodejs : install Watchman] ***********************************************
fatal: [machine1]: FAILED! => {"changed": true, "cmd": "files/install-watchman.bash", "delta": "0:00:00.002997", "end": "2019-01-27 16:01:50.093530", "msg": "non-zero return code", "rc": 127, "start": "2019-01-27 16:01:50.090533", "stderr": "/bin/sh: 1: files/install-watchman.bash: not found", "stderr_lines": ["/bin/sh: 1: files/install-watchman.bash: not found"], "stdout": "", "stdout_lines": []}
to retry, use: --limit @/vagrant/ansible/site.retry
(If it helps, this is the version info for ansible:)
vagrant@ubuntu-xenial:~$ ansible --version
ansible 2.7.6
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/home/vagrant/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python2.7/dist-packages/ansible
executable location = /usr/bin/ansible
python version = 2.7.12 (default, Nov 12 2018, 14:36:49) [GCC 5.4.0 20160609]
I put together a test of this to see: https://github.com/farrellit/ansible-demonstrations/tree/master/shell-cwd
It has convinced me that the short answer is probably, ansible roles' shell
tasks will by default have the working directory of the playbook that include that role.
It basically comes down to a role like this ( the rest of that dir is tooling to make it run):
- shell: pwd
register: shellout
- debug: var=shellout.stdout
- shell: pwd
args:
chdir: "{{role_path}}"
register: shellout2
- debug: var=shellout2.stdout
This has shown:
PLAY [localhost] ***********************************************************************************************************************************************************************************************************************
TASK [shelldir : command] **************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]
TASK [shelldir : debug] ****************************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
"shellout.stdout": "/code"
}
TASK [shelldir : command] **************************************************************************************************************************************************************************************************************
changed: [127.0.0.1]
TASK [shelldir : debug] ****************************************************************************************************************************************************************************************************************
ok: [127.0.0.1] => {
"shellout2.stdout": "/code/roles/shelldir"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
127.0.0.1 : ok=4 changed=2 unreachable=0 failed=0
That the current working directory for roles is not role_path
. In my case it is the role of the playbook that invoked the task. It might be something else in the case of an included playbook or tasks file from a different directory (I'll leave that as an exercise for you, if you care). I set that execution to run from /tmp
, so I don't think it would matter the current working directory of the shell that ran ansible-playbook
.
Shell will execute the command on the remote. You have copied the script to /home/vagrant/install-watchman.bash
on your remote. Therefore you have to use that location for executing on the remote as well.
- name: install Watchman
shell: /home/vagrant/install-watchman.bash
a relative path will work as well, if your ansible user is the user "vagrant"
- name: install Watchman
shell: install-watchman.bash
Side note:
I would recommend to use command
instead of shell
whenever possible: shell vs command Module
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With