'Copy one file between remote hosts with Ansible

I have 2 remote servers (Prod and Demo) and I would like to copy the latest file from a particular folder in Prod to another folder in Demo. Only one file is to be copied.

I can find the latest file in Prod using:

- name: Get files in folder
  find:
    paths: "/path_in_prod/arch/"
  register: found_files
  become: true
  become_user: root
  delegate_to: "{{ prod_server }}"
  when: copy_content_from_prod is defined

- name: Get latest file
  set_fact:
    latest_file: "{{ found_files.files | sort(attribute='mtime', reverse=true) | first }}"
  become: true
  become_user: root
  delegate_to: "{{ prod_server }}"
  when: copy_content_from_prod is defined

I can check I have the correct file (debug).

When I try to copy the file with

- name: Fetch the file from prod
  fetch: src= {{ latest_file.path }} dest=buffer/ flat=yes
  delegate_to: "{{ prod_server }}"

- name: Copy the file to demo
  copy: src=buffer/{{ latest_file.path | basename }} dest=/path_in_demo/in

I get a "File not found" error. But if I look for the file it is there (latest_file.path on Prod).

this is the error message

fatal: [demoServerHost -> ProdServerHost ]: FAILED! => {"changed": false, "msg": "file not found: "}

I do not know if I am interpreting the error message correctly but it seems to be looking in Demo in order to copy onto Prod?



Solution 1:[1]

In such case the synchronize_module might be the solution.

- name: Synchronize file from PROD to DEMO
  synchronize:
    src: "/tmp/test.txt"
    dest: "/tmp/test.txt"
    mode: push
  delegate_to: "{{ prod_server }}"
  when: "{{ demo_server }}"

which is "copying" a file from the production node to the demo node.

There are also a lot of answers under How to copy files between two nodes using Ansible.

Solution 2:[2]

I have faced a similar issue, where the copy task hangs indefinitely. Here is my example which is not site specific (will identify the site and user using the options). The easiest solution I have found is to scp directly using the shell module:

-   name: scp files onto '{{ target_destination }}' looping for each file on '{{ target_source }}'
    shell: 'scp {{ hostvars[target_source].ansible_user }}@{{ hostvars[target_source].ansible_host }}:/opt/{{ hostvars[target_source].ansible_user }}/{{ item }} /opt/{{ destuser.stdout }}'
    loop: '{{ diffout.stdout_lines }}'
    when: diffout.stdout != ""

Some notes:

  • "target_source" and "target_destination" are defined using the extra-vars option
  • diffout is an earlier task comparing the folders on "Prod" and "Demo" and shows any new files to copy
  • this task is run on the "target_destination" (in my case Prod)
  • hostvars[target_source] will look at the variables for the "target_source" host in the inventory
  • this serves as a "pull" from Demo to Prod in my case, if your "Demo" doesn't have permissions, then you could delegate the task to "Prod" and rearrange the scp to look for "Demo" vars to push from "Prod"

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 U880D
Solution 2 Svampebob Cameron