20

In my playbook I have

- name: Grab h5bp/server-configs-nginx
  git:  repo=https://github.com/h5bp/server-configs-nginx.git
        dest=/tmp/server-configs-nginx
        version="3db5d61f81d7229d12b89e0355629249a49ee4ac"
        force=yes

- name: Copy over h5bp configuration
  command: cp -r /tmp/server-configs-nginx/{{ item }} /etc/nginx/{{ item }}
  with_items:
    - "mime.types"
    - "h5bp/"

Which raises the warning in ansible-lint:

[ANSIBLE0006] cp used in place of copy module
/Users/austinpray/Dropbox/DEV/opensauce/bedrock-ansible/roles/nginx/tasks/main.yml:0
Task/Handler: Copy over h5bp configuration

So this raises the question: is there a better way to do this with ansible modules rather than a command?

Austin Pray
  • 4,926
  • 2
  • 22
  • 30

6 Answers6

16

You can use the synchronize module with mode='pull'

- name: Copy over h5bp configuration
 synchronize: mode=pull src=/tmp/server-configs-nginx/{{ item }} dest=/etc/nginx/{{ item }} 
 with_items:
   - "mime.types"
   - "h5bp/"

Note: To copy remote-to-remote, use the same command and add delegate_to (as remote source) and current inventory_host (as remote dest)

Nathan Smith
  • 683
  • 1
  • 10
  • 24
ant31
  • 4,471
  • 4
  • 15
  • 20
  • In ansible 2.2, using sychronize module as described in this answer or using command module with 'cp' as described in the question are the only ways of copying directories from remote to remote. – Alan Evangelista Dec 13 '16 at 19:25
  • 1
    This sounds promising but I can't make sense of your "note:". Can you post a full example for doing deep remote-to-remote file copies? I'm trying to copy a web-root directory from an NFS share onto the local disk of each web server in a pool. Say from /nfs/www to /var/www. – Idris Apr 25 '17 at 23:55
9

Currently, command is your best option. There's no remote-to-remote option. Here's a thread about it: How to move/rename a file using an Ansible task on a remote system

You have a couple other options:

  • you could use the file module to make a symlink (by setting src, path, and state=link.
  • you could check out the repo on the Ansible server and then use copy. This is a more common model for deploying code.
  • you can keep using command but wrap it with a stat conditional so it only overwrites once. This is especially helpful if you use notify to restart nginx.

Finally, it looks like you might be doing a "deploy by git". That isn't always the best choice, especially if you don't "own" that repo. But it could be fine- just a bit of code smell.

Community
  • 1
  • 1
tedder42
  • 23,519
  • 13
  • 86
  • 102
  • "Finally, it looks like you might be doing a 'deploy by git'." Here is the context. This is only a small portion of setting up the server. I basically am just grabbing some useful server configs from a remote repo maintained by the community. https://github.com/roots/bedrock-ansible/issues/31 – Austin Pray Aug 29 '14 at 23:17
  • ended up just ditching ansible-lint haha – Austin Pray Sep 12 '14 at 17:29
7

Ansible 2.0 brings the remote_src parameter to the copy module: http://docs.ansible.com/ansible/copy_module.html

Now you just need to do something like:

- name: Copy over h5bp configuration
  copy: src=/tmp/server-configs-nginx/{{ item }} dest=/etc/nginx/{{ item }} remote_src=yes
  with_items:
    - "mime.types"
    - "h5bp"
Pricey
  • 518
  • 1
  • 8
  • 20
  • 2
    Remote copy (copy module with remote_src parameter set to 'true') does not support recursive copy of directory and the question is about copying directories, so this answer is useless – Alan Evangelista Dec 13 '16 at 19:05
  • @AlanEvangelista hmm you're right, bah that sucks. I think the answer is still useful though as it's still possible to list all files. – Pricey Dec 19 '16 at 19:46
5

Another way is to zip your folder before and use the unarchive ansible module:

- name: copy your folder using a work around
  unarchive: src=your.zip dest=/destinationfolder
  become: yes

This will unzip your folder on your destination so you have a folder copy ;-) but don't forget to have unzip package on your target machine.

RHEL :

yum install unzip -y


Debian :

apt install unzip

tgr
  • 3,557
  • 4
  • 33
  • 63
Hassan Boutougha
  • 3,871
  • 1
  • 17
  • 17
1
  • copy: src={{ item }} dest=/etc/fooapp/ directory_mode=yes

user directory_mode field.

0

You could use with_fileglob: http://docs.ansible.com/ansible/playbooks_loops.html#id4

# copy each file over that matches the given pattern
- copy: src={{ item }} dest=/etc/fooapp/ owner=root mode=600
  with_fileglob:
    - /playbooks/files/fooapp/*
slm
  • 15,396
  • 12
  • 109
  • 124