Linux – Ansible Copy module & become – Permission denied

ansiblelinuxpermissions

I am running an ansible script on localhost to copy a folder to another location.
However,

- name: Copy Network
  become: yes
  become_user: root
  copy:
    src: /d/
    dest: "/dest/d/"
    mode: 0644
  tags: [network]

is giving me [Errno 13] Permission denied: b'd/f1'. I was expecting become_user will make the command execute as root, didn't work.
The permission of this file is 0600(root:root).

Can you please give me pointers to get access to this file to copy it using ansible?

Note:

  • sudo ansible-playbook p.yml works perfectly however, I don't want to use sudo with ansible command if it's not required and ansible has a trick for it.

  • command: cp -r /d/ /dest/d/ works without appending sudo to the ansible command (ansible-playbook p.yml). However, I don't want to use command if I can help it because of idempotence & copy module has mode option required for the task.

Best Answer

The error says: The user who is running ansible-playbook can't read /d/f1.

In the module copy, become: yes applies only to writing the file not to reading it. As a result, the module works as expected.

"an error occurred while trying to read the file '/d/f1': [Errno 13] Permission denied: '/d/f1'"

Details

By default module copy copy 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: yes means Ansible escalate privilege in the remote host, but not in the local master. Despite the fact that the task is running in localhost, i.e both master and the remote host is localhost, become: yes will apply only to writing the file not to reading it.

If it wasn't this way become: yes would automatically escalate the privilege in master. This might be a security problem.


Q: "Is there any workaround for it?"

A: 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 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'''

One of the solutions is to make the file readable for the user running the playbook. For example, make the file readable for others by the superuser in the first play and use it in the second play

shell> cat playbook.yml
- hosts: localhost
  become: true
  tasks:
    - file:
        path: f1
        mode: o+r

- hosts: test_01
  become: true
  tasks:
    - copy:
        src: f1
        dest: /tmp

This would work only if the user is allowed to escalate to root at the controller, of course.