Question:
I need to copy file form machine A to machine B whereas my control machine from where i run all my ansible tasks is machine C(local machine)
I have tried the following:
Use scp command in shell module of ansible
1 2 3 4 5 6 |
hosts: machine2 user: user2 tasks: - name: Copy file from machine1 to machine2 shell: scp user1@machine1:/path-of-file/file1 /home/user2/file1 |
This approach just goes on and on never ends.
use fetch & copy modules
1 2 3 4 5 6 7 8 9 10 11 12 |
hosts: machine1 user: user1 tasks: - name: copy file from machine1 to local fetch: src=/path-of-file/file1 dest=/path-of-file/file1 hosts: machine2 user: user2 tasks: - name: copy file from local to machine2 copy: src=/path-of-file/file1 dest=/path-of-file/file1 |
This approach throws me an error as follows:
1 2 |
error while accessing the file /Users/ |
Any suggestions would be helpful.
Answer:
As ant31 already pointed out you can use the synchronize
module to 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 task’s delegate_to
parameter (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
1 2 3 4 5 6 7 8 |
- 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 sound like 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 machine and ServerB
.
Placing the task on ServerA
1 2 3 4 5 6 7 8 9 |
- 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.