Ansible: copy a directory content to another directory

218,349

Solution 1

Resolved answer: To copy a directory's content to another directory I use the next:

- name: copy consul_ui files
  command: cp -r /home/{{ user }}/dist/{{ item }} /usr/share/nginx/html
  with_items:
   - "index.html"
   - "static/"

It copies both items to the other directory. In the example, one of the items is a directory and the other is not. It works perfectly.

Solution 2

You could use the synchronize module. The example from the documentation:

# Synchronize two directories on one remote host.
- synchronize:
    src: /first/absolute/path
    dest: /second/absolute/path
  delegate_to: "{{ inventory_hostname }}"

This has the added benefit that it will be more efficient for large/many files.

Solution 3

EDIT: This solution worked when the question was posted. Later Ansible deprecated recursive copying with remote_src

Ansible Copy module by default copies files/dirs from control machine to remote machine. If you want to copy files/dirs in remote machine and if you have Ansible 2.0, set remote_src to yes

- name: copy html file
  copy: src=/home/vagrant/dist/ dest=/usr/share/nginx/html/ remote_src=yes directory_mode=yes

Solution 4

To copy a directory's content to another directory you CAN use ansibles copy module:

- name: Copy content of directory 'files'
  copy:
    src: files/    # note the '/' <-- !!!
    dest: /tmp/files/

From the docs about the src parameter:

If (src!) path is a directory, it is copied recursively...
... if path ends with "/", only inside contents of that directory are copied to destination.
... if it does not end with "/", the directory itself with all contents is copied.

Solution 5

The simplest solution I've found to copy the contents of a folder without copying the folder itself is to use the following:

- name: Move directory contents
  command: cp -r /<source_path>/. /<dest_path>/

This resolves @surfer190's follow-up question:

Hmmm what if you want to copy the entire contents? I noticed that * doesn't work – surfer190 Jul 23 '16 at 7:29

* is a shell glob, in that it relies on your shell to enumerate all the files within the folder before running cp, while the . directly instructs cp to get the directory contents (see https://askubuntu.com/questions/86822/how-can-i-copy-the-contents-of-a-folder-to-another-folder-in-a-different-directo)

Share:
218,349

Related videos on Youtube

Asier Gomez
Author by

Asier Gomez

DevOps / Computer Science Engineer

Updated on July 08, 2022

Comments

  • Asier Gomez
    Asier Gomez almost 2 years

    I am trying to copy the content of dist directory to nginx directory.

    - name: copy html file
      copy: src=/home/vagrant/dist/ dest=/usr/share/nginx/html/
    

    But when I execute the playbook it throws an error:

    TASK [NGINX : copy html file] **************************************************
    fatal: [172.16.8.200]: FAILED! => {"changed": false, "failed": true, "msg": "attempted to take checksum of directory:/home/vagrant/dist/"}
    

    How can I copy a directory that has another directory and a file inside?

    • Bruce P
      Bruce P about 8 years
      From the Ansible docs for the copy module: "The copy module copies a file on the local box to remote locations". You say that there are two files in /home/vagrant/dist. Are those located on the host you are running Ansible from, or on the host with the IP 172.16.8.200?
    • Asier Gomez
      Asier Gomez about 8 years
      Hello @BruceP yes the directory /home/vagrant/dist is in the remote machine, as #helloV says I have put remote_src=yes but the problem is that "copy" doesn't work with directorys, and inside the directory "dist" there is a file and a directory. How can I copy the file and the directory? Thanks
    • holms
      holms about 6 years
      @Asier it does - directory_mode=yes
    • Asier Gomez
      Asier Gomez about 6 years
      @holms Yes I try my code but it doesn't copy if there are directories with files inside another directory.
  • Asier Gomez
    Asier Gomez about 8 years
    Inside "/home/vagrant/dist/" directory there is a file and another directory, I can copy the file, but if I copy bouth, it throws the next error: 'attempted to take checksum of directory:' what could it be? I think the copy only works with files and not with directorys. @helloV
  • tread
    tread over 7 years
    Hmmm what if you want to copy the entire contents? I notied that * doesn't work
  • DMCoding
    DMCoding about 7 years
    You can prevent the find command showing as 'changed' with changed_when: false
  • Mircea Vutcovici
    Mircea Vutcovici about 7 years
    "Currently remote_src does not support recursive copying" - See: docs.ansible.com/ansible/copy_module.html
  • agmezr
    agmezr almost 7 years
    Is there a way to use the copy module but specify that the copy is local to local? When I use copy module insted of command: cp it takes an absurd amount of time
  • Asier Gomez
    Asier Gomez almost 7 years
    See the next post: stackoverflow.com/questions/40955440/… I'm not sure if it is what you are asking @agmezr
  • agmezr
    agmezr almost 7 years
    @AsierGomez after searching a lot I decided to use shell: 'cp -r {{ source_dir }}/{{ item }} {{ deploy_dir }}' it's a lot faster that using copy (maybe i'm doing something wrong)
  • techraf
    techraf over 6 years
    This is nonsensical. You specifically wrote "to recursively copy the contents", but your tasks flatten the structure and copy all files from subdirectories to a single directory.
  • holms
    holms about 6 years
    I'd say you only need to use synchronize when you want to move huge amount of files from/to remote location, because it's using rsync, what's the point to use rsync locally? maybe there's, I don't know :)
  • pkaramol
    pkaramol almost 6 years
    Is inventory_hostname a built in ansible variable or we set it somehow?
  • Aidan Feldman
    Aidan Feldman almost 6 years
    @pkaramol Built in.
  • Younes
    Younes about 5 years
    It is planed that copy module will support recursive copy with remote_src: yes in Ansible 2.8 (see Allow copy module to work with recursive and remote_src).
  • Younes
    Younes about 5 years
    It is planed that copy module will support recursive copy with remote_src: yes in Ansible 2.8 (see Allow copy module to work with recursive and remote_src).
  • finnmglas
    finnmglas over 3 years
    Please do not answer old questions (here:4 years ago) unless you have something important to add that the other answers fail at / are inefficient with. Your answer seems to be a duplicate of all the other ones
  • cjnash
    cjnash about 3 years
    +1 This should be the correct answer! No command, no creating a register of files to copy... Just using the copy module how it is intended.
  • andymel
    andymel about 3 years
    It is possible with ansibles copy module, have a look at my answer
  • andymel
    andymel about 3 years
    At least now it is possible with ansibles copy module, have a look at my answer
  • GreenLake4964
    GreenLake4964 about 2 years
    I am using Ansible 2.4.4, the "remote_src" attribute doesn't support recursive copying. The "directory_mode" attribute is probably for copying from LOCAL to REMOTE recursively.