Copie varios archivos con Ansible


103

¿Cómo puedo copiar más de un archivo en nodos remotos por Ansible en una tarea?

Intenté duplicar la línea del módulo de copia en mi tarea para definir archivos, pero solo copia el primer archivo.

Respuestas:


131

Puedes usar el with_fileglobbucle para esto:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_fileglob:
    - /playbooks/files/fooapp/*

3
Este enfoque podría ayudarme si tuviera todos mis archivos en la misma raíz para copiarlos en una máquina remota, ¿qué hay de tener algunos archivos en varios directorios? Por ejemplo, quiero copiar 3 archivos de 3 directorios diferentes
Mark

Oye, estoy tratando de mover todos los archivos de mi, /roles/db/filespero no puedo hacerlo funcionar con este método. Lo he intentado, with_fileglob: - /roles/db/file/* pero el camino no va bien
Batman

La gran desventaja de este método es que aplana la estructura del directorio.
Quintin Par

114
- 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

¿Es posible tener esta solución con el destconjunto como variable? { src: 'containerizers', dest: {{ containerizers }} }.
Gesias

2
@Gesias, sí. En realidad, ambos lados pueden ser variables:{ src: '{{ source.var }}', dest: '{{ dest.var }}' }
ntwrkguru

16

Puede usar with_together para este propósito:

- name: Copy multiple files to multiple directories
  copy: src={{ item.0 }} dest={{ item.1 }}
  with_together:
    - [ 'file1', 'file2', 'file3' ]
    - [ '/dir1/', '/dir2/', '/dir3/' ]

Aunque funciona, esto no es semánticamente limpio, hay opciones más limpias.
plesiv

11

Si necesita más de una ubicación, necesita más de una tarea. Una tarea de copia puede copiar solo desde una ubicación (incluidos varios archivos) a otra en el nodo.

- 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/*

- nombre: copia archivo1 copia: src = / archivo1 dest = / destino / archivo1 - nombre: copia archivo2 copia: src = / archivo2 dest = / destino / archivo2
Marca el

Depende. Más simple y probablemente más limpio, pero se puede hacer utilizando estructuras de datos más complejas, como una lista de diccionarios anónimos con datos de origen y destino, enlazados con_items. Es lo mismo en cualquier idioma, tienes que tomar una decisión. Hay casos en los que una función de delegación es más eficiente y fácil de mantener que una larga serie de instrucciones if copiadas / pegadas. Soy ese fenómeno que prefiere mantener un código conciso bien estructurado que una lista larga y tediosa de directivas casi idénticas, pero no asumo que todos estén de acuerdo. Haga lo que pueda mantener para usted.
Paul Hodges

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

solo una nota al margen de que el findmódulo solo funciona para ansible 2.x pero no para ansible 1.x
Arbab Nazar

He arreglado su respuesta porque ha mencionado stdout_linesen el valor de retorno, pero no es aplicable para el findmódulo. Sólo se tiene files, examinedy matchedcomo valores de retorno. Espero que ayuden a otros
Arbab Nazar

2
¿Alguien ha podido hacer que esto funcione para copiar archivos en nodos remotos? findsolo parece mirar el sistema remoto, no permitiendo tomar nada del nodo de administración. Estas respuestas, usando with_fileglob, parecen ser más adecuadas: stackoverflow.com/a/42290160/272387 , stackoverflow.com/a/36720342/272387 .
Richlv

7

Desde Ansible 2.5, las with_*construcciones están en desuso y se loopdebe usar la sintaxis. Un ejemplo práctico sencillo:

- 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


4

O puede usar with_items:

- copy:
    src: "{{ item }}"
    dest: /etc/fooapp/
    owner: root
    mode: 600
  with_items:
    - dest_dir

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

6
Una buena respuesta contiene no solo código, sino también algunas explicaciones o referencias de documentación.
Laurenz Albe

Los módulos find, set_fact y copy se explican en la documentación de ansible. Lea acerca de los filtros, que también se explica en la documentación de ansible si desea saber más sobre esta sección (- "{{find_files.files | map (attribute'path ') | list}}")
Fredric Andersson

1

Puede recorrer la variable con la lista de directorios:

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

1

Utilice el siguiente código fuente para copiar varios archivos en su máquina cliente.


 - 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

Nota:

Si está pasando varias rutas mediante el uso de variables, entonces

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

Si está pasando la ruta utilizando una variable para diferentes elementos, entonces

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


0

copymodule es una herramienta incorrecta para copiar muchos archivos y / o estructura de directorio, use synchronizemodule en su lugar que usa rsynccomo backend. Eso sí, requiere estar rsyncinstalado tanto en el controlador como en el host de destino. Es realmente poderoso, verifique la documentación de ansible .

Ejemplo: copiar archivos del builddirectorio (con subdirectorios) del controlador al /var/www/htmldirectorio en el host de destino:

synchronize:
  src: ./my-static-web-page/build/
  dest: /var/www/html
  rsync_opts:
    - "--chmod=D2755,F644" # copy from windows - force permissions
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.