Trying to copy script from local to remote and run

Hey all, me again! So I’ve got this playbook that should run fine but it dies at trying to copy. Now I don’t know if it’s because it can’t find it locally having the problem copying it remotely. Here it is:

cat check_for_reboot.yml

cat check_for_reboot.yml
---
- name: Check for reboot
  hosts: testserver
  become: yes

  vars_files:
    - passwd.yml
    - vars.yml

  vars:
    script_dir: "/home/tsg/scripts"

  tasks:
    - name: Does script directory exist?
      stat:
        path: "{{ script_dir }}"
      register: dir_exists

You don't need to do this, the file module will check if the directory exist and create if it doesn't exist.

    - name: Does script exist?
      stat:
        path: "{{ script_dir }}/needs-restarting.py"
      register: fic

You don't need to do this, the copy module will check if the file exist and create/copy if it doesn't exist.

    - name: Create scripts dir
      file:
        state: directory
        path: "{{ script_dir }}"
        owner: tsg
        group: tsg
        mode: 0755
      when: dir_exists.stat.exists == false

    - name: Copy script
      copy:
        src: "{{ script_dir }}/needs-restarting.py"
        dest: "{{ script_dir }}/needs-restarting.py"
        owner: tsg
        group: tsg
        mode: 0755
      when: fic.stat.exists == false

    - name: Check for reboot
      command: "{{ script_dir }}/needs-restarting.py -r"
      register: reboot_reqd
      ignore_errors: true
      changed_when: false

    - name: "Rebooting {{ ansible_hostname }}"
      shell: sleep 1 && reboot
      async: 30
      poll: 1
      ignore_errors: true
      when: reboot_reqd.rc == 1

If you are using Ansible 2.7 I recommend using the reboot module.
https://docs.ansible.com/ansible/2.7/modules/reboot_module.html#reboot-module

If not you should change it to this to avoid errors.

  - name: "Rebooting {{ ansible_hostname }}"
    shell: sleep 2 && reboot
    async: 1
    poll: 0
    when: reboot_reqd.rc == 1

    - name: Wait for ssh to come back available
      wait_for:
        host: "{{
(ansible_ssh_host|default(ansible_host))|default(inventory_hostname) }}"
        port: 22
        search_regex: OpenSSH
        delay: 10
        timeout: 240
      vars:
        ansible_connection: local
      when: reboot_reqd.rc == 1

Instead of wait_for I highly recommend using wait_for_connection instead because that module will check the remote host is ready to execute Ansible modules before it continues.
(With the reboot module this is not needed)

Output:
TASK [Create scripts dir]
*************************************************************************************************************************************************
changed: [testserver]

TASK [Copy script]
********************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use
-vvv. The error was: If you are using a module and expect the file to exist
on the remote, see the remote_src option
fatal: [testserver]: FAILED! => {"changed": false, "msg": "Could not find
or access '/home/tsg/scripts/needs-restarting.py' on the Ansible
Controller.\nIf you are using a module and expect the file to exist on the
remote, see the remote_src option"}

Okay, so I know that file is on the src server (ansible server).

[tsg@server]$ pwd
/home/tsg/scripts
[tsg@server scripts]$ll
-rwxr-x---. 1 root tsg 8432 Aug 23 17:57 needs-restarting.py

The dot after the permission indicate that your file has a SELinux ACL, so you should check your SELinux log to see if SELinux is blocking Ansible to access the file.

So I simplified my playbook a bit. I disabled selinux on both servers and I’m still getting an error.

Tilde for home directory is a concept for the shell not Ansible, you need to use relative or absolute path.

I’ve tried that with the same results. Hmm

The best is probably starting with basic.

src: in copy module is where the file is on the machine ansible-playbook is executed aka Ansible controller, dest: is where to copy the file on remote host.
The file need to be accessible by the user executing ansible-playbook.

Since you have turned off SELinux that should not cause any problem, so if you still have problem after checking the above it would run
   strace -o strace.log ansible-playbook ......
And check the strace.log to see if that has some clues.

So I found that by putting the file in question within the local ansible roles directory, it worked. It somehow didn’t have access to the directory it resided in (Which is actually the users home directory!) Anyway, very strange! Thanks so much for your help in narrowing down the culprits.