Update: If you can escalate the privilege to root on localhost master the solution is to set remote_src: true
(credit @ivandov)
- copy:
src: /d/
dest: /dest/d/
mode: '0644'
remote_src: true
become: true
become_user: root
The below details describe the case when you're not able to escalate to root on localhost. Given the file on localhost
shell> ll /tmp/test/d/f1
-rw-r----- 1 root root 0 Aug 25 23:23 /tmp/test/d/f1
the module copy works as expected
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
become: true
become_user: root
First, it tries to read the file and fails
fatal: [localhost]: FAILED! =>
msg: 'an error occurred while trying to read the file ''/tmp/test/d/f1'': [Errno 13] Permission denied: b''/tmp/test/d/f1''. [Errno 13] Permission denied: b''/tmp/test/d/f1'''
By default, module copy copies files from src (local path to a file to copy to the remote server) to dest (remote absolute path where the file should be copied to). In this case, become: true
means Ansible escalates privilege on the remote host, but not on the localhost master. Despite the fact that the task is running on localhost, i.e. both master and the remote host are localhost, without remote_src: true
the setting become: true
applies only to writing the file not to reading it. If you can't escalate to root on the localhost setting remote_src: true
- copy:
src: /tmp/test/d/
dest: /tmp/test/dest/
remote_src: true
become: true
become_user: root
will fail
fatal: [localhost]: FAILED! => changed=false
ansible_facts:
discovered_interpreter_python: /usr/bin/python3
module_stderr: |-
sudo: a password is required
module_stdout: ''
msg: |-
MODULE FAILURE
See stdout/stderr for the exact error
rc: 1
Q: "Is there any workaround for it?"
A: Without the escalation to the root, there is no workaround. It would violate the ownership and permissions of the files. For example, given the file at the controller
shell> ll f1
-rw-rw---- 1 root root 0 Sep 13 18:17 f1
The playbook below was started by an unprivileged user
shell> cat playbook.yml
- hosts: test_01
become: true
tasks:
- copy:
src: f1
dest: /tmp
will crash
TASK [copy] ****
fatal: [test_01]: FAILED! =>
msg: 'an error occurred while trying to read the file ''/scratch/f1'':
[Errno 13] Permission denied: b''/scratch/f1'''
If you can't escalate to root on the localhost master the solution is to make the file readable for the user running the playbook.