Ansible Dev Ops

Ansible Copy Command

Ansible copy module allows you to copy files and folders from the local machine to remote servers. The copy module is versatile. You can perform a lot of complex tasks with it. Let’s dive into some tasks you need to perform regularly.

Copying Files from Local to Remote

Most of the times you will be copying files from local to remote servers. Here is a playbook example of performing such a task.

---
- hosts: webservers
  tasks:
  - name: Copy file to a remote server
    copy:
     src: ~/test.txt
     dest: /tmp

In the above example, we are targeting all the webservers group in our Ansible inventory. The source is the test.txt residing in the home directory of our local machine and the destination is the /tmp folder on the remote machine.

$ ansible-playbook 1_copy_to_remote.yml
 
PLAY [webservers]
****************************************************************************
 
TASK [Gathering Facts]
****************************************************************************
ok: [172.17.0.3]
 
TASK [Ansible copy file to remote server]
****************************************************************************
changed: [172.17.0.3]
 
PLAY RECAP
*****************************************************************************
172.17.0.3                 : ok=2    changed=1    unreachable=0    failed=0

If we run the playbook, we should see the results like above.

The default permissions are set to 0644 on the remote machine:

# ls -alsh test.txt
0 -rw-rw-r-- 1 a_user a_user 0 Apr 20 08:49 test.txt

You can change that by adding the mode parameter:

---
- hosts: webservers
  tasks:
  - name: Copy file to a remote server
    copy:
    src: ~/test.txt
    dest: /tmp
     mode: 0744

So your permissions on the remote will look like this:

# ls -alsh test.txt
0 -rwxr--r-- 1 a_user a_user 0 Apr 20 08:54 test.txt

Copying Directories from Local to Remote

For copying directories, you have two options. If you put a / after the directory name, then it will copy anything inside that directory to the destination folder. If you don’t put the /, then it will first create the directory in the destination and then copy everything inside.

Let’s try the copy module with the following directory located in our local home folder:

testdir/
|-- nested1
|   `-- test1.txt
|-- nested2
|   `-- test2.txt
`-- test0.txt

If we use the following code:

---
- hosts: webservers
tasks:
- name: Copy directory to remote server
copy:
src: ~/testdir
dest: /tmp

Then we get the following on the remote server:

tmp/
`-- testdir
|-- nested1
|   `-- test1.txt
|-- nested2
|   `-- test2.txt
`-- test0.txt

Copying Files between Directories on Remote Machines

Ansible copy allows you to copy files from one directory to another on the same remote machine. But you can perform this only for files, you can’t copy directories. You have to use the remote_src parameter to let Ansible know your intentions.

---
- hosts: webservers
tasks:
- name: Copy file between directories on a remote server
copy:
src: /tmp/test.txt
dest: ~/test.txt
remote_src: yes

The above code will copy /tmp/test.txt to the home directory of the user (/home/[username]/).

 Copying Files with Multiple Parameters

You can pass individual parameters for files.

---
- hosts: webservers
tasks:
- name: Copy files with multiple changes
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
mode: "{{item.mode}}"
with_items:

- { src: '~/testdir2/test1.txt', dest: '/tmp/a.txt', mode: '0644'}
- { src: '~/testdir2/test2.txt', dest: '/tmp/b.txt', mode: '0755'}
- { src: '~/testdir2/test3.txt', dest: '/tmp/c.txt', mode: '0644'}

In the above example, we are renaming and setting individual permissions for the files. The Ansible output looks like this:

$ ansible-playbook 4_copy_to_remote_with_multiple_parameters.yml
 
PLAY [webservers]
******************************************************************
 
TASK [Gathering Facts]
******************************************************************
ok: [172.17.0.3]
 
TASK [Copy files with multiple changes]
******************************************************************
changed: [172.17.0.3] => (item={u'dest': u'/tmp/a.txt', u'src': u'~/testdir2/test1.txt',
u'mode': u'0644'})
changed: [172.17.0.3] => (item={u'dest': u'/tmp/b.txt', u'src': u'~/testdir2/test2.txt',
u'mode': u'0755'})
changed: [172.17.0.3] => (item={u'dest': u'/tmp/c.txt', u'src': u'~/testdir2/test3.txt',
u'mode': u'0644'})
 
PLAY RECAP
**************************************************************************
172.17.0.3                 : ok=2    changed=1    unreachable=0    failed=0

Creating Content on Remote Servers

You can use copy module to create content on remote servers directly from the playbook file. Here is an example:

---
- hosts: webservers
tasks:
- name: Use ansible copy to create content in a remote server
copy:
content: "Hello Server!\n"
dest: /tmp/hello.txt

This will create the hello.txt file on the remote server that will contain “Hello Server!” text.

# cat /tmp/hello.txt
Hello Server

Conclusion

Ansible copy is a useful module that helps you copy files across servers. It should make your configuration tasks easier.

Further Study:

http://docs.ansible.com/ansible/latest/modules/copy_module.html

About the author

Zak H

Zak H

Zak H. lives in Los Angeles. He enjoys the California sunshine and loves working in emerging technologies and writing about Linux and DevOps topics.