Distribuire una cartella di file modello usando ansible


47

Esiste un modo semplice per distribuire una cartella piena di una cartella modello .j2 in una casella linux, usando lo stesso nome del modello, ma senza l'estensione .j2, anziché utilizzare il modulo modello per ciascun file?

In questo momento ho una lunga lista di:

- name: create x template
  template:
    src=files/x.conf.j2
    dest=/tmp/x.conf
    owner=root
    group=root
    mode=0755
  notify:
    - restart myService

Risposte:


68

È possibile utilizzare with_fileglobper ottenere l'elenco dei file dalla directory del modello e utilizzare i filtri per rimuovere l'estensione j2 in questo modo.

- name: create x template
  template:
    src: {{ item }}
    dest: /tmp/{{ item | basename | regex_replace('\.j2','') }}
  with_fileglob:
    - ../templates/*.j2

11
nota with_fileglobfunziona sempre da files/, è possibile arrivare ai modelli con ../templates/mytemplate/*. stackoverflow.com/a/27407566/1695680
ThorSummoner

2
Grazie, è molto utile. Ho scoperto che ho dovuto usare due barre rovesciate per sfuggire al periodo letterale nella funzione regex_replace. Forse perché avevo l'intera porzione del modello dest tra virgolette doppie in modo da poter utilizzare il formato YAML per la definizione dell'attività (che preferisco rispetto al formato a riga singola).
Tony Cesaro,

1
questo presuppone solo file dal vivo all'interno della cartella dei modelli, se è necessario per supportare sia le directory ei file all'interno dei modelli di cartella, quindi è necessario with_filetree - vedere stackoverflow.com/questions/41667864/...
danday74

Una nota che regex_replacedovrebbe corrispondere alla fine della riga \.j2$per i casi in cui potrebbe esistere il modello all'interno del nome file.
Brett Ryan,

20

Michael DeHaan (creatore di Ansible) ha pubblicato un post su CoderWall che parla di un problema molto simile. Puoi modificarlo ed espanderlo in base alle tue esigenze (come permessi e proprietà). Parte pertinente del post è qui:


Questo può essere semplificato usando " with_items" e una singola notifyistruzione. Se una qualsiasi delle attività cambia, il servizio verrà notificato esattamente nello stesso modo in cui deve essere riavviato al termine dell'esecuzione del playbook.

 - name:  template everything for fooserv
   template: src={{item.src}} dest={{item.dest}}
   with_items:
      - { src: 'templates/foo.j2', dest: '/etc/splat/foo.conf' }
      - { src: 'templates/bar.j2', dest: '/etc/splat/bar.conf' }
   notify: 
      - restart fooserv

Si noti che dal momento che abbiamo attività che accettano più di un argomento unico, non solo diciamo " item" nella template:riga " ", ma usiamo with_itemscon una variabile hash (dizionario). Puoi anche mantenerlo un po 'più breve usando gli elenchi, se lo desideri. Questa è una preferenza stilistica:

 - name:  template everything for fooserv
   template: src={{item.0}} dest={{item.1}}
   with_items:
      - [ 'templates/foo.j2', '/etc/splat/foo.conf' ]
      - [ 'templates/bar.j2', '/etc/splat/bar.conf' ]
   notify: 
      - restart fooserv

Ovviamente potremmo anche definire l'elenco su cui stavi camminando in un altro file, come un " groupvars/webservers" file per definire tutte le variabili necessarie per il webserversgruppo o un file YAML caricato dalla varsfilesdirettiva " " all'interno del playbook. Guarda come questo può ripulire se lo facciamo.

- name: template everything for fooserv
  template: src={{item.src}} dest={{item.dest}}
  with_items: {{fooserv_template_files}}
  notify: 
      - restart fooserv

5
Un metodo più semplice potrebbe essere quello di scrivere template: src=templates/{{item}}.j2 dest=/etc/splat/{{item}}.confe quindi utilizzare un semplice elenco di elementi:with_items: - foo - bar
Ethan

Questo in realtà sembra sbagliato adesso. La linea del modello corretta sarebbe template: src={{item.src}} dest={{item.dest}}(cioè non ${var}ma piuttosto {{var}})
Fabiano Francesconi il

@FabianoFrancesconi aggiornato.
Mxx,

9

La risposta di Russel funziona ma deve essere migliorata

- name: create x template
- template: src={{ item }} dest=/tmp/{{ item | basename | regex_replace('.j2','') }}
- with_fileglob:
   - files/*.j2

I primi di tutti i $ devono andare perché era regex sbagliato nel regex_replace. In secondo luogo, tutti i file dovrebbero trovarsi nella directory dei file anziché nella directory dei modelli


4
Benvenuti in Server Fault! La tua risposta suggerisce che una soluzione praticabile alla domanda è disponibile attraverso una risposta precedente, quindi sarebbe più appropriato come una modifica di quella risposta. Ti preghiamo di considerare di eliminare la tua risposta attuale e di suggerire una modifica alla risposta di Russell.
Paul,

7

Ho scritto un plug-in di ricerca filetree che può aiutare con le azioni sugli alberi dei file.

È possibile ricorrere ai file in una struttura di file e in base alle proprietà dei file eseguire azioni (ad esempio modello o copia). Poiché viene restituito il percorso relativo, è possibile ricreare facilmente il filetree sui sistemi di destinazione.

- name: Template complete tree
  template:
    src: '{{ item.src }}'
    dest: /web/{{ item.path }}
    force: yes
  with_filetree: some/path/
  when: item.state == 'file'

Rende i playbook più leggibili.


Non è stato ancora unito :-(
Morgan Christiansson,

2
È stato unito.
Dag Wieers,

C'è un modo per filtrare dire solo i file * .conf?
Andrey,

Certo, nella parte "quando:" puoi scrivere un'espressione adatta alle tue necessità.
Dag Wieers,

1
Il plugin non è lento, è il processo di creazione di modelli e copia di ogni singolo file che lo rallenta. Ma questo non ha quasi nulla a che fare con il plug-in, il plug-in potrebbe essere utile per altre cose oltre al modello o alla copia.
Dag Wieers,

3

Il comando seguente ha funzionato per me per fare una ricerca ricorsiva per i file j2 nei template e spostarlo nella destinazione. Spero che aiuti qualcuno a cercare una copia ricorsiva di modelli a destinazione.

     - name: Copying the templated jinja2 files
       template: src={{item}} dest={{RUN_TIME}}/{{ item | regex_replace(role_path+'/templates','') | regex_replace('\.j2', '') }}
       with_items: "{{ lookup('pipe','find {{role_path}}/templates -type f').split('\n') }}"

1

C'è la possibilità di prendere automaticamente l'elenco dei file effettivi dalla directory e di iterarli in seguito.

- name:         get the list of templates to transfer
  local_action: "shell ls templates/* | sed 's~.*/~~g'"
  register:     template_files

- name:         iterate and send templates
  template:     src=templates/{{ item }} dest=/mydestination/{{ item }}
  with_items:
  - "{{ template_files.stdout.splitlines() }}"

Nota l'avvertenza standard sulla divisione in newline: i nomi dei file possono contenere newline. Una soluzione più sicura consiste nell'utilizzare un'utilità di shell che supporti print0, come find, e quindi dividere \u0000.
Dejay Clayton,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.