Bereitstellen eines Ordners mit Vorlagendateien mithilfe von Ansible


47

Gibt es eine einfache Möglichkeit, einen Ordner mit dem Ordner template .j2 in einer Linux-Box bereitzustellen, der denselben Namen wie die Vorlage verwendet, jedoch ohne die Erweiterung .j2, anstatt das Vorlagenmodul für jede Datei zu verwenden?

Im Moment habe ich eine lange Liste von:

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

Antworten:


67

Sie können with_fileglobdie Liste der Dateien aus Ihrem Vorlagenverzeichnis abrufen und Filter verwenden, um die j2-Erweiterung wie folgt zu entfernen.

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

11
Hinweis with_fileglobfunktioniert immer ab files/, mit können Sie zu Vorlagen gelangen ../templates/mytemplate/*. stackoverflow.com/a/27407566/1695680
ThorSummoner

2
Danke, das ist super hilfreich. Ich stellte fest, dass ich zwei Backslashes verwenden musste, um die Literalperiode in der Funktion regex_replace zu umgehen. Vielleicht, weil ich den gesamten Dest-Template-Teil in doppelten Anführungszeichen hatte, damit ich das YAML-Format für die Aufgabendefinition verwenden konnte (was ich dem Einzeiler-Format vorzuziehen habe).
Tony Cesaro

1
dies setzt voraus , nur Dateien Live in den Ordner Vorlagen, wenn Sie beide Verzeichnisse und Dateien innerhalb der Vorlagen unterstützen müssen Ordner dann müssen Sie with_filetree - siehe stackoverflow.com/questions/41667864/...
danday74

Ein Hinweis, der regex_replaceam Ende der Zeile \.j2$für Fälle übereinstimmen sollte, in denen das Muster möglicherweise im Dateinamen enthalten ist.
Brett Ryan

20

Michael DeHaan (Schöpfer von Ansible) hat einen Beitrag auf CoderWall verfasst , in dem es um ein sehr ähnliches Thema geht. Sie können es an Ihre Anforderungen anpassen und erweitern (z. B. Berechtigungen und Eigentumsrechte). Ein relevanter Teil des Beitrags ist hier:


Dies kann durch die Verwendung von " with_items" und einer einzelnen notifyAnweisung vereinfacht werden . Wenn sich eine der Aufgaben ändert, wird der Dienst genau so benachrichtigt, wie er am Ende der Playbook-Ausführung neu gestartet werden muss.

 - 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

Beachten Sie, dass wir, da wir Aufgaben haben, die mehr als ein eindeutiges Argument enthalten, nicht nur " item" in der template:Zeile ' ' angeben , sondern with_itemsmit einer Hash-Variablen (Wörterbuch) verwenden. Sie können es auch etwas kürzer halten, indem Sie Listen verwenden, wenn Sie möchten. Dies ist eine stilistische Präferenz:

 - 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

Natürlich können wir auch die Liste, über die Sie gegangen sind, in einer " groupvars/webservers" anderen Datei definieren, z. B. eine Datei, in der alle für die webserversGruppe benötigten Variablen definiert werden , oder eine YAML - Datei, die aus der varsfilesDirektive " " im Playbook geladen wird . Schauen Sie, wie das aufräumen kann, wenn wir es tun.

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

5
Eine einfachere Methode könnte sein, zu schreiben template: src=templates/{{item}}.j2 dest=/etc/splat/{{item}}.confund dann eine einfache Liste von Elementen zu verwenden:with_items: - foo - bar
Ethan

Das sieht jetzt tatsächlich falsch aus. Die richtige Template-Zeile wäre template: src={{item.src}} dest={{item.dest}}(also nicht ${var}, sondern {{var}})
Fabiano Francesconi

@FabianoFrancesconi aktualisiert.
Mxx

9

Die Antwort von Russel funktioniert, ist aber verbesserungswürdig

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

Erstens muss das $ gehen, da es im regex_replace ein falscher regulärer Ausdruck war. Zweitens sollten sich alle Dateien im Dateiverzeichnis und nicht im Vorlagenverzeichnis befinden


4
Willkommen bei Server Fault! Ihre Antwort schlägt vor, dass eine praktikable Lösung für die Frage durch eine vorherige Antwort verfügbar ist. Daher wäre eine Bearbeitung dieser Antwort besser geeignet. Bitte überlegen Sie, ob Sie Ihre aktuelle Antwort löschen und Russell eine Änderung vorschlagen möchten.
Paul

7

Ich habe ein Dateibaum-Such-Plugin geschrieben, das bei Aktionen in Dateibäumen helfen kann.

Sie können Dateien in einem Dateibaum rekursiv bearbeiten und anhand von Dateieigenschaften Aktionen ausführen (z. B. Vorlage oder Kopie). Da der relative Pfad zurückgegeben wird, können Sie den Dateibaum auf den Zielsystemen problemlos neu erstellen.

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

Es sorgt für lesbarere Spielbücher.


Es wurde noch nicht zusammengeführt :-(
Morgan Christiansson

2
Es wurde zusammengeführt.
Dag Wieers

Gibt es eine Möglichkeit, beispielsweise nur * .conf-Dateien zu filtern?
Andrey

Sicher, im "when:" Teil können Sie einen Ausdruck schreiben, der Ihren Bedürfnissen entspricht.
Dag Wieers

1
Das Plugin ist nicht langsam, sondern es ist der Prozess des Vorlagen- und Kopierens jeder einzelnen Datei, der es langsam macht. Das hat aber kaum etwas mit dem Plugin zu tun, das Plugin könnte auch für andere Dinge nützlich sein, als Vorlagen zu erstellen oder zu kopieren.
Dag Wieers

3

Mit dem folgenden Befehl konnte ich eine rekursive Suche nach j2-Dateien in Vorlagen durchführen und diese an das Ziel verschieben. Ich hoffe, es hilft jemandem, der nach einer rekursiven Kopie der Vorlagen zum Ziel sucht.

     - 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

Es besteht die Möglichkeit, die Liste der aktuellen Dateien automatisch aus dem Verzeichnis zu holen und anschließend zu iterieren.

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

Beachten Sie den Standard-Vorbehalt zum Teilen von Zeilenumbrüchen - Dateinamen können Zeilenumbrüche enthalten. Eine sicherere Lösung besteht darin, ein Shell-Dienstprogramm zu verwenden, das unterstützt print0, wie z. B. findund dann zu teilen \u0000.
Dejay Clayton
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.