sudo(become) difference between "copy" module and "command" module

Hello,

“become” works perfectly fine with “command” module. But not with “copy” module. Am I doing something wrong here.

Working playbook:

  • name: demo
    hosts: localhost
    tasks:
  • name: copy
    command: cp /etc/ssh/sshd_config /tmp/sshd_config
    become: yes
  • name: edit
    lineinfile:
    path: /tmp/sshd_config
    regexp: ‘^PermitRootLogin’
    line: “PermitRootLogin yes”
    become: yes

working logs:

$ ap lineinfile.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match ‘all’

PLAY [demo] ************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************
ok: [localhost]

TASK [copy] ************************************************************************************************************************
changed: [localhost]

TASK [edit] ************************************************************************************************************************
changed: [localhost]

PLAY RECAP *************************************************************************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

Problematic playbook:

  • name: demo
    hosts: localhost
    tasks:
  • name: copy
    copy:
    src: /etc/ssh/sshd_config
    dest: /tmp/sshd_config
    become: yes
  • name: edit
    lineinfile:
    path: /tmp/sshd_config
    regexp: ‘^PermitRootLogin’
    line: “PermitRootLogin yes”
    become: yes

Logs for problematic playbook:

$ap zz.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match ‘all’

PLAY [demo] ************************************************************************************************************************

TASK [Gathering Facts] *************************************************************************************************************
ok: [localhost]

TASK [copy] ************************************************************************************************************************
fatal: [localhost]: FAILED! => {“msg”: “an error occurred while trying to read the file ‘/etc/ssh/sshd_config’: [Errno 13] Permission denied: b’/etc/ssh/sshd_config’”}

PLAY RECAP *************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0

Hello,

"become" works perfectly fine with "command" module. But not with
"copy" module. Am I doing something wrong here.

*_Working playbook:_*
- name: demo
hosts: localhost
tasks:
- name: copy
command: cp /etc/ssh/sshd_config /tmp/sshd_config
become: yes
- name: edit
lineinfile:
path: /tmp/sshd_config
regexp: '^PermitRootLogin'
line: "PermitRootLogin yes"
become: yes

working logs:
$ ap lineinfile.yml
[WARNING]: provided hosts list is empty, only localhost is available.
Note that the implicit localhost does not match 'all'

PLAY [demo]
************************************************************************************************************************

TASK [Gathering Facts]
*************************************************************************************************************
ok: [localhost]

TASK [copy]
************************************************************************************************************************
changed: [localhost]

TASK [edit]
************************************************************************************************************************
changed: [localhost]

PLAY RECAP
*************************************************************************************************************************
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0
ignored=0

*_Problematic playbook:_*
- name: demo
hosts: localhost
tasks:
- name: copy
copy:
src: /etc/ssh/sshd_config
dest: /tmp/sshd_config
become: yes
- name: edit
lineinfile:
path: /tmp/sshd_config
regexp: '^PermitRootLogin'
line: "PermitRootLogin yes"
become: yes

Logs for problematic playbook:
$ap zz.yml
[WARNING]: provided hosts list is empty, only localhost is available.
Note that the implicit localhost does not match 'all'

PLAY [demo]
************************************************************************************************************************

TASK [Gathering Facts]
*************************************************************************************************************
ok: [localhost]

TASK [copy]
************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "an error occurred while trying
to read the file '/etc/ssh/sshd_config': [Errno 13] Permission denied:
b'/etc/ssh/sshd_config'"}

You want `remote_src: yes`... otherwise it's trying to read the file from the controller.

V/r,
James Cassell

Thanks for your email. This playbook is for testing purpose. I wanted src to be from controller only.

>
> > Hello,
> >
> > "become" works perfectly fine with "command" module. But not with
> > "copy" module. Am I doing something wrong here.
> >
> > *_Working playbook:_*
> > - name: demo
> > hosts: localhost
> > tasks:
> > - name: copy
> > command: cp /etc/ssh/sshd_config /tmp/sshd_config
> > become: yes
> > - name: edit
> > lineinfile:
> > path: /tmp/sshd_config
> > regexp: '^PermitRootLogin'
> > line: "PermitRootLogin yes"
> > become: yes
> >
> > working logs:
> > $ ap lineinfile.yml
> > [WARNING]: provided hosts list is empty, only localhost is available.
> > Note that the implicit localhost does not match 'all'
> >
> > PLAY [demo]
> > ************************************************************************************************************************
> >
> > TASK [Gathering Facts]
> > *************************************************************************************************************
> > ok: [localhost]
> >
> > TASK [copy]
> > ************************************************************************************************************************
> > changed: [localhost]
> >
> > TASK [edit]
> > ************************************************************************************************************************
> > changed: [localhost]
> >
> > PLAY RECAP
> > *************************************************************************************************************************
> > localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0
> > ignored=0
> >
> >
> > *_Problematic playbook:_*
> > - name: demo
> > hosts: localhost
> > tasks:
> > - name: copy
> > copy:
> > src: /etc/ssh/sshd_config
> > dest: /tmp/sshd_config
> > become: yes
> > - name: edit
> > lineinfile:
> > path: /tmp/sshd_config
> > regexp: '^PermitRootLogin'
> > line: "PermitRootLogin yes"
> > become: yes
> >
> > Logs for problematic playbook:
> > $ap zz.yml
> > [WARNING]: provided hosts list is empty, only localhost is available.
> > Note that the implicit localhost does not match 'all'
> >
> > PLAY [demo]
> > ************************************************************************************************************************
> >
> > TASK [Gathering Facts]
> > *************************************************************************************************************
> > ok: [localhost]
> >
> > TASK [copy]
> > ************************************************************************************************************************
> > fatal: [localhost]: FAILED! => {"msg": "an error occurred while trying
> > to read the file '/etc/ssh/sshd_config': [Errno 13] Permission denied:
> > b'/etc/ssh/sshd_config'"}
> >
>
> You want `remote_src: yes`... otherwise it's trying to read the file from the controller.

Thanks for your email. This playbook is for testing purpose. I wanted
src to be from controller only.

In that case, you'll need to make sure the src file can be read by the user running ansible. sshd_config is not world readable by default.

V/r,
James Cassell

Hello,

Which is why I’ve mentioned “become: yes” option. Like I’ve mentioned in starting of this thread, if I run the exact same playbook with “command” module, permission issue does not come. Only with “copy” module, it complains about permission issue. Please note I’ve used “become” in both the cases.

Hello,

but become applies on target host, not controller. And, as stated
before, in the first playbook you're copying with cp sshd_config of
the remote host to /tmp/sshd_config. Instead in the second one you're
copying sshd_config from controller to /tmp/sshd_config of the remote
host.
Even if the host is localhost and localhost is the controller, it is
treated like any remote host. Become is applied inside the connection
to remote host (even if connection: local), not when executing
ansible.

Luca

Hello,

Thanks a lot. Its clear now. I have used “remote_src” to apply “become” logic.

Regards,
Mukuntha.