Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible Recursive Directory Copy

Tags:

ansible

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?

like image 296
Patrick Avatar asked Aug 02 '17 01:08

Patrick


3 Answers

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

copy module is for copying.

like image 138
techraf Avatar answered Nov 15 '22 10:11

techraf


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")
like image 24
Marinos An Avatar answered Nov 15 '22 12:11

Marinos An


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

like image 23
Saurav Sahu Avatar answered Nov 15 '22 10:11

Saurav Sahu