Ansible Recursive Directory Copy

11,822

Solution 1

file module is not for copying the files, but for setting attributes of files on the target.

copy module is for copying.

Solution 2

Providing some additional information to the accepted answer..

Recursive copy using directory paths has the following disadvantages:

  • you cannot get changed state information per file copied
  • so --check and --check --diff flags won't show anything
  • you cannot include/exclude specific files/directories to/from the recursion
  • performing corrective changes after the bulk copy will never produce a state with changed=0 and could also affect files that already existed on remote host.

There seems to be a more powerful way to perform a recursive copy, which is to use with_filetree combined with when

- name: "create-remote-dirs"
  file:
    path: /dest/dir/{{item.path}}
    state: directory
    mode:  '0775'
  with_filetree: sourceDir/
  when: item.state == 'directory'
- name: "copy-files"
  copy:
    src: "{{item.src}}"
    dest: /dest/dir/{{item.path}}
    mode:  '0744'
  with_filetree: sourceDir/
  # combinations of 'is' and 'is not' can be used below.
  when: item.state == 'file' 
        and item.path is not search("excludedDir/*")
        and item.path is not search("*.bak")

Solution 3

Source files and directories can be stored inside files directory. If you put them in other folders it may not get found.

Copy file:

copy:
  src: src_filename 
  dest: to_be_parent/src_filename

results into to_be_parent/src_filename. Destination filename may or may not be equal to src filename.

Copy directory:

copy:
  src: mydirectory
  dest: to_be_parent

results into to_be_parent/mydirectory

copy:
  src: mydirectory/
  dest: to_be_parent

results into to_be_parent/contents_of_mydirectory

Not so desired result in below case:

copy:
  src: mydirectory
  dest: to_be_parent/mydirectory

results into to_be_parent/mydirectory/mydirectory/contents_of_mydirectory

Share:
11,822
Patrick
Author by

Patrick

Updated on June 14, 2022

Comments

  • Patrick
    Patrick over 1 year

    Ansible version: 2.2.1.0

    I'm having trouble copying the contents of a directory to a destination host in Ansible. My role directory structure looks like this:

    roles/server/
    ├── defaults
    │   └── main.yml
    ├── files
    │   ├── Common-x86_64.repo
    │   ├── docker-ce-stable.repo
    |
    ├── handlers
    │   └── main.yml
    ├── meta
    │   └── main.yml
    ├── README.md
    ├── tasks
    │   ├── main.yml
    │   └── packages.yml
    ├── templates
    ├── tests
    │   ├── inventory
    │   └── test.yml
    └── vars
        └── main.yml
    

    There are a lot (about 12 more) repos in the files directory, I've omitted most for the sake of keeping it short. I'm running this code in packages.yml

    - name: 1. Setup Repos
         file:
           src: files/
           dest: /etc/yum.repos.d/
           owner: root
           group: root
           mode: 0644
    

    Even though the task is completing without error, nothing is copying into /etc/yum.repos.d/ on the target machine:

    ls /etc/yum.repos.d/
    CentOS-Base.repo       CentOS-Media.repo    CentOS-fasttrack.repo
    CentOS-CR.repo         CentOS-Sources.repo
    CentOS-Debuginfo.repo  CentOS-Vault.repo
    

    I read on the documentation page that ending a source directory with a / causes the contents to be copied recursively. What am I doing wrong?