Patrick
Patrick

Reputation: 303

Ansible Recursive Directory Copy

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?

Upvotes: 6

Views: 18381

Answers (3)

Saurav Sahu
Saurav Sahu

Reputation: 13924

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

Upvotes: 4

Marinos An
Marinos An

Reputation: 10808

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")

Upvotes: 5

techraf
techraf

Reputation: 68449

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

copy module is for copying.

Upvotes: 3

Related Questions