How can I copy files between two managed nodes using Ansible?

As @ant31 already pointed out, you can use the synchronize module for this. By default, the module transfers files between the control machine and the current remote host (inventory_host), however that can be changed using the delegate_to parameter of a task (it’s important to note that this is a parameter of the task, not of the module).

You can place the task on either ServerA or ServerB, but you have to adjust the direction of the transfer accordingly (using the mode parameter of synchronize).

Placing the task on ServerB

- hosts: ServerB
  tasks:
    - name: Transfer file from ServerA to ServerB
      synchronize:
        src: /path/on/server_a
        dest: /path/on/server_b
      delegate_to: ServerA

This uses the default mode: push, so the file gets transferred from the delegate (ServerA) to the current remote (ServerB).

This might look strange, since the task has been placed on ServerB (via hosts: ServerB). However, one has to keep in mind that the task is actually executed on the delegated host, which, in this case, is ServerA. So pushing (from ServerA to ServerB) is indeed the correct direction. Also remember that we cannot simply choose not to delegate at all, since that would mean that the transfer happens between the control node and ServerB.

Placing the task on ServerA

- hosts: ServerA
  tasks:
    - name: Transfer file from ServerA to ServerB
      synchronize:
        src: /path/on/server_a
        dest: /path/on/server_b
        mode: pull
      delegate_to: ServerB

This uses mode: pull to invert the transfer direction. Again, keep in mind that the task is actually executed on ServerB, so pulling is the right choice.

Leave a Comment