Wdrażanie folderu plików szablonów za pomocą ansible

47

Czy istnieje prosty sposób na wdrożenie folderu pełnego folderu .j2 szablonu w polu linux, używając tej samej nazwy co szablon, ale bez rozszerzenia .j2, zamiast używać modułu szablonu dla każdego pliku?

W tej chwili mam długą listę:

- name: create x template
  template:
    src=files/x.conf.j2
    dest=/tmp/x.conf
    owner=root
    group=root
    mode=0755
  notify:
    - restart myService
Trololololol
źródło

Odpowiedzi:

67

Możesz użyć, with_fileglobaby uzyskać listę plików z katalogu szablonów i użyć filtrów, aby usunąć rozszerzenie j2 w ten sposób ..

- name: create x template
  template:
    src: {{ item }}
    dest: /tmp/{{ item | basename | regex_replace('\.j2','') }}
  with_fileglob:
    - ../templates/*.j2
Russell
źródło
11
Uwaga with_fileglobzawsze działa od files/, możesz dostać się do szablonów za pomocą ../templates/mytemplate/*. stackoverflow.com/a/27407566/1695680
ThorSummoner
2
Dzięki, to jest bardzo pomocne. Odkryłem, że musiałem użyć dwóch odwrotnych ukośników, aby uciec od literału w funkcji regex_replace. Być może dlatego, że miałem całą część szablonu docelowego w podwójnych cudzysłowach, więc mogłem użyć formatu YAML do definicji zadania (który wolę niż format jednowierszowy).
Tony Cesaro
1
zakłada to, że tylko pliki znajdują się w folderze szablonów, jeśli potrzebujesz obsługiwać zarówno katalogi, jak i pliki w folderze szablonów, potrzebujesz with_filetree - patrz stackoverflow.com/questions/41667864/...
danday74
Uwaga, która regex_replacepowinna pasować na końcu linii \.j2$w przypadkach, w których wzorzec może istnieć w nazwie pliku.
Brett Ryan
20

Michael DeHaan (twórca Ansible) napisał post na CoderWall, który mówi o bardzo podobnym problemie. Możesz go dostosować i rozszerzyć zgodnie z własnymi potrzebami (takimi jak uprawnienia i własność). Odpowiednia część postu znajduje się tutaj:


Można to uprościć, używając „ with_items” i pojedynczej notifyinstrukcji. Jeśli którekolwiek z zadań ulegnie zmianie, usługa zostanie o tym powiadomiona dokładnie tak samo, jak musi zostać uruchomiona ponownie na końcu uruchomienia playbooka.

 - 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

Zauważ, że ponieważ mamy zadania, które wymagają więcej niż jednego unikalnego argumentu, nie mówimy tylko „ item” w template:wierszu „ ”, ale używamy with_itemsze zmienną hash (słownik). Jeśli chcesz, możesz też nieco go skrócić, używając list. To jest preferencja stylistyczna:

 - 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

Oczywiście możemy również zdefiniować listę, w której chodziłeś w innym pliku, np. Plik „ groupvars/webservers” do zdefiniowania wszystkich zmiennych potrzebnych dla webserversgrupy, lub plik YAML załadowany z varsfilesdyrektywy „ ” wewnątrz podręcznika. Zobacz, jak możemy to wyczyścić, jeśli to zrobimy.

- name: template everything for fooserv
  template: src={{item.src}} dest={{item.dest}}
  with_items: {{fooserv_template_files}}
  notify: 
      - restart fooserv
Mxx
źródło
5
Prostszą metodą może być napisanie template: src=templates/{{item}}.j2 dest=/etc/splat/{{item}}.conf, a następnie użycie prostej listy pozycji:with_items: - foo - bar
Ethan
To właściwie wygląda teraz źle. Prawidłową linią szablonu byłoby template: src={{item.src}} dest={{item.dest}}(tj. Nie, ${var}ale raczej {{var}})
Fabiano Francesconi,
Zaktualizowano @FabianoFrancesconi.
Mxx
9

Odpowiedź Russela działa, ale wymaga poprawy

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

Najpierw trzeba odejść od wszystkich $, ponieważ był to zły regex w regex_replace. Po drugie, wszystkie pliki powinny znajdować się w katalogu plików, a nie w katalogu szablonów

HJ_VORTEX
źródło
4
Witaj w Server Fault! Twoja odpowiedź sugeruje, że możliwe jest rozwiązanie problemu na podstawie poprzedniej odpowiedzi, dlatego byłoby bardziej odpowiednie jako edycja tej odpowiedzi. Proszę rozważyć usunięcie aktualnej odpowiedzi i zasugerowanie zmiany w odpowiedzi Russella.
Paul
7

Napisałem wtyczkę do wyszukiwania plików, która może pomóc w działaniach na drzewach plików.

Możesz rekursować pliki w drzewie plików i na podstawie właściwości pliku wykonywać działania (np. Szablon lub kopiować). Ponieważ zwracana jest ścieżka względna, możesz z łatwością odtworzyć drzewo plików w systemie docelowym.

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

To sprawia, że ​​bardziej czytelne podręczniki.

Dag Wieers
źródło
Nie został jeszcze scalony :-(
Morgan Christiansson
2
Zostało połączone.
Dag Wieers
Czy istnieje sposób na filtrowanie plików powiedz tylko * .conf?
Andrey
Jasne, w części „kiedy:” możesz napisać wyrażenie, które odpowiada twoim potrzebom.
Dag Wieers
1
Wtyczka nie jest powolna, to proces tworzenia szablonów i kopiowania każdego pliku osobno powoduje, że jest powolny. Ale to nie ma nic wspólnego z wtyczką, wtyczka może być przydatna do innych celów niż tworzenie szablonów lub kopiowanie.
Dag Wieers
3

Poniższe polecenie pomogło mi przeprowadzić rekurencyjne wyszukiwanie plików j2 w szablonach i przenieść je do miejsca docelowego. Mam nadzieję, że pomoże to komuś, kto szuka rekurencyjnej kopii szablonów do miejsca docelowego.

     - 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') }}"
Rudzik
źródło
1

Istnieje możliwość automatycznego pobrania listy rzeczywistych plików z katalogu, a następnie ich iteracji.

- 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() }}"
Roman Dolejsi
źródło
Zwróć uwagę na standardowe zastrzeżenie dotyczące podziału na nowej linii - nazwy plików mogą zawierać nowe linie. Bezpieczniejszym rozwiązaniem jest użycie narzędzia powłoki, które obsługuje print0, takie jak find, a następnie dzieli \u0000.
Dejay Clayton