Copier plusieurs fichiers avec Ansible

104

Comment puis-je copier plusieurs fichiers dans des nœuds distants par Ansible dans une tâche?

J'ai essayé de dupliquer la ligne du module de copie dans ma tâche pour définir les fichiers, mais cela ne copie que le premier fichier.

marque
la source

Réponses:

131

Vous pouvez utiliser la with_fileglobboucle pour cela:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_fileglob:
    - /playbooks/files/fooapp/*
Arbab Nazar
la source
3
Cette approche pourrait m'aider si j'avais tous mes fichiers dans la même racine pour les copier sur une machine distante, qu'en est-il d'avoir des fichiers dans différents répertoires. Par exemple, je veux copier 3 fichiers de 3 répertoires différents
Mark
Hé, j'essaye de déplacer tous les fichiers de mon /roles/db/filesmais je ne peux pas le faire fonctionner avec cette méthode. J'ai essayé with_fileglob: - /roles/db/file/* mais ça ne va pas bien le chemin
Batman
Le gros inconvénient de cette méthode est qu'elle aplatit la structure des répertoires.
Quintin Par
115
- name: Your copy task
  copy: src={{ item.src }} dest={{ item.dest }}
  with_items:
    - { src: 'containerizers', dest: '/etc/mesos/containerizers' }
    - { src: 'another_file', dest: '/etc/somewhere' }
    - { src: 'dynamic', dest: '{{ var_path }}' }
  # more files here
guenhter
la source
Est-il possible d'avoir cette solution avec l' destensemble comme variable? { src: 'containerizers', dest: {{ containerizers }} }.
Gesias
2
@Gesias, oui. En fait, les deux côtés peuvent être des variables:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru
16

Vous pouvez utiliser with_together à cet effet:

- name: Copy multiple files to multiple directories
  copy: src={{ item.0 }} dest={{ item.1 }}
  with_together:
    - [ 'file1', 'file2', 'file3' ]
    - [ '/dir1/', '/dir2/', '/dir3/' ]
Mircea Husz
la source
Bien que cela fonctionne, ce n'est pas sémantiquement propre - il existe des options plus propres.
plesiv
11

Si vous avez besoin de plus d'un emplacement, vous avez besoin de plus d'une tâche. Une tâche de copie ne peut copier qu'un emplacement (y compris plusieurs fichiers) vers un autre sur le nœud.

- copy: src=/file1 dest=/destination/file1
- copy: src=/file2 dest=/destination/file2

# copy each file over that matches the given pattern
- copy: src={{ item }} dest=/destination/
  with_fileglob:
    - /files/*
flxPeters
la source
- nom: copie fichier1 copie: src = / fichier1 dest = / destination / fichier1 - nom: copie fichier2 copie: src = / fichier2 dest = / destination / fichier2
Marquer le
Dépend. Plus simple et probablement plus propre, mais peut être fait en utilisant des structures de données plus complexes, telles qu'une liste de dictionnaires anonymes avec des données source et cible, en boucle avec_items. C'est la même chose dans n'importe quelle langue - vous devez faire un jugement. Il y a des cas où une fonction de délégation est plus efficace et maintenable qu'une longue série d'instructions copier / coller if. Je suis ce monstre qui préfère conserver le morceau concis de code bien structuré qu'une longue et fastidieuse liste de directives presque identiques, mais je ne suppose pas que tout le monde est d'accord. Faites ce qui est maintenable pour vous.
Paul Hodges
8

Depuis Ansible 2.5, les with_*constructions sont obsolètes et la loopsyntaxe doit être utilisée. Un exemple pratique simple:

- name: Copy CA files
  copy:
    src: '{{item}}'
    dest: '/etc/pki/ca-trust/source/anchors'
    owner: root
    group: root
    mode: 0644
  loop:
    - symantec-private.crt
    - verisignclass3g2.crt

Richlv
la source
7
- hosts: lnx
  tasks:
    - find: paths="/appl/scripts/inq" recurse=yes patterns="inq.Linux*"
      register: file_to_copy
    - copy: src={{ item.path }} dest=/usr/local/sbin/
      owner: root
      mode: 0775
      with_items: "{{ files_to_copy.files }}"
Diego Roberto Dos Santos
la source
juste un côté note que le findmodule ne fonctionne que pour ansible 2.x mais pas pour ansible 1.x
Arbab Nazar
J'ai corrigé votre réponse car vous avez mentionné le stdout_linesdans la valeur de retour mais n'est pas applicable pour le findmodule. Il a seulement files, examinedet matchedque les valeurs de retour. J'espère que cela aidera les autres
Arbab Nazar
2
Quelqu'un a-t-il pu faire fonctionner cela pour copier des fichiers sur des nœuds distants? findne semble regarder que le système distant, ne permettant pas de récupérer quoi que ce soit du nœud de gestion. Ces réponses, en utilisant with_fileglob, semblent plus appropriées: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv
4

Ou vous pouvez utiliser with_items:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_items:
    - dest_dir
MxWild
la source
3
- name: find inq.Linux*
  find:  paths="/appl/scripts/inq" recurse=yes patterns="inq.Linux*"
  register: find_files


- name: set fact
  set_fact:
    all_files:
      - "{{ find_files.files | map(attribute='path') | list }}"
  when: find_files > 0


- name: copy files
  copy:
    src: "{{ item }}"
    dest: /destination/
  with_items: "{{ all_files }}"
  when: find_files > 0
Fredric Andersson
la source
6
Une bonne réponse contient non seulement du code, mais aussi des explications ou des références de documentation.
Laurenz Albe
Les modules find, set_fact et copy sont tous expliqués dans la documentation d'ansible. Lisez à propos des filtres, également expliqués dans la documentation ansible si vous voulez en savoir plus sur cette section (- "{{find_files.files | map (attribute'path ') | list}}")
Fredric Andersson
1

Vous pouvez parcourir la variable avec la liste des répertoires:

- name: Copy files from several directories
  copy:
    src: "{{ item }}"
    dest: "/etc/fooapp/"
    owner: root
    mode: "0600"
  loop: "{{ files }}"
  vars:
    files:
      - "dir1/"
      - "dir2/"
Stan
la source
1

Utilisez le code source suivant pour copier plusieurs fichiers sur votre ordinateur client.


 - name: Copy data to the client machine
   hosts: hostname
   become_method: sudo
   become_user: root
   become: true
   tasks: 
     # Copy twice as sometimes files get skipped (mostly only one file skipped from a folder if the folder does not exist)
     - name: Copy UFO-Server 
       copy:
         src: "source files path"
         dest: "destination file path"
         owner: root
         group: root
         mode: 0644
         backup: yes
       ignore_errors: true

Remarque:

Si vous passez plusieurs chemins en utilisant la variable, alors

src: "/ root / {{élément}}"

Si vous passez le chemin en utilisant une variable pour différents éléments, alors

src: "/ root / {{item.source_path}}"

Shaha Nawaj Mulla
la source
0

copymodule est un mauvais outil pour copier de nombreux fichiers et / ou une structure de répertoires, utilisez synchronizeplutôt le module qui utilise rsynccomme backend. Attention, il doit être rsyncinstallé à la fois sur le contrôleur et sur l'hôte cible. C'est vraiment puissant, vérifiez la documentation disponible .

Exemple - copier des fichiers du buildrépertoire (avec sous-répertoires) du contrôleur vers le /var/www/htmlrépertoire sur l'hôte cible:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
mrówa
la source