Déploiement d'un dossier de fichiers modèles à l'aide de ansible

47

Existe-t-il un moyen simple de déployer un dossier contenant le modèle .j2 dans une boîte Linux, en utilisant le même nom que le modèle, mais sans l'extension .j2, plutôt que d'utiliser le module de modèle pour chaque fichier?

En ce moment, j'ai une longue liste de:

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

Réponses:

68

Vous pouvez utiliser with_fileglobpour obtenir la liste des fichiers de votre répertoire de modèles et utiliser des filtres pour supprimer l’extension j2.

- name: create x template
  template:
    src: {{ item }}
    dest: /tmp/{{ item | basename | regex_replace('\.j2','') }}
  with_fileglob:
    - ../templates/*.j2
Russell
la source
11
note with_fileglobfonctionne toujours à partir de files/, vous pouvez obtenir des modèles avec ../templates/mytemplate/*. stackoverflow.com/a/27407566/1695680
ThorSummoner
2
Merci, c'est super utile. J'ai découvert que je devais utiliser deux barres obliques inverses pour échapper à la période littérale dans la fonction regex_replace. Peut-être parce que j'avais la totalité de la portion du modèle de destination entre guillemets afin que je puisse utiliser le format YAML pour la définition de tâche (que je préfère par rapport au format à une ligne).
Tony Cesaro
1
cela suppose que seuls les fichiers stockés dans le dossier templates sont présents. Si vous devez prendre en charge à la fois les répertoires et les fichiers du dossier templates, vous avez besoin de with_filetree - voir stackoverflow.com/questions/41667864/…
danday74
Une note qui regex_replacedevrait correspondre en fin de ligne \.j2$pour les cas où le modèle peut exister à l'intérieur du nom de fichier.
Brett Ryan
20

Michael DeHaan (créateur d'Ansible) a publié un article sur CoderWall qui parle d'un problème très similaire. Vous pouvez l'ajuster et le développer en fonction de vos besoins (autorisations et droits de propriété, par exemple). La partie pertinente de l'article est ici:


Ceci peut être simplifié en utilisant " with_items" et une seule notifydéclaration. Si l'une des tâches change, le service en sera informé exactement de la même manière qu'il doit redémarrer à la fin de l'exécution du livre de lecture.

 - 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

Notez que comme nous avons des tâches qui prennent plus d’un argument unique, nous ne disons pas simplement " item" dans la template:ligne ", mais nous les utilisons with_itemsavec une variable hash (dictionnaire). Vous pouvez également le raccourcir un peu en utilisant des listes, si vous le souhaitez. C'est une préférence stylistique:

 - 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

Bien sûr, nous pourrions également définir la liste que vous parcouriez dans un autre fichier, comme un groupvars/webserversfichier " " permettant de définir toutes les variables nécessaires au webserversgroupe, ou un fichier YAML chargé à partir de la varsfilesdirective " " du playbook. Regardez comment cela peut nettoyer si nous le faisons.

- name: template everything for fooserv
  template: src={{item.src}} dest={{item.dest}}
  with_items: {{fooserv_template_files}}
  notify: 
      - restart fooserv
Mxx
la source
5
Une méthode plus simple pourrait consister à écrire template: src=templates/{{item}}.j2 dest=/etc/splat/{{item}}.conf, puis à utiliser une liste simple d'éléments:with_items: - foo - bar
Ethan
Cela semble effectivement faux maintenant. La ligne de modèle correcte serait template: src={{item.src}} dest={{item.dest}}(c'est-à-dire pas ${var}mais plutôt {{var}})
Fabiano Francesconi
@FabianoFrancesconi mis à jour.
Mxx
9

La réponse de Russel fonctionne mais doit être améliorée

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

Les premiers de tous les $ doivent disparaître car c'était une mauvaise regex dans le regex_replace. Deuxièmement, tous les fichiers doivent se trouver dans le répertoire files plutôt que dans le répertoire templates

HJ_VORTEX
la source
4
Bienvenue sur Server Fault! Votre réponse suggère qu'une solution viable à la question est disponible via une réponse précédente. Il serait donc plus approprié de la réviser. Veuillez envisager de supprimer votre réponse actuelle et de suggérer une modification de la réponse de Russell.
Paul
7

J'ai écrit un plugin de recherche filetree qui peut aider avec des actions sur les arbres de fichiers.

Vous pouvez récupérer des fichiers dans une arborescence et, en fonction de leurs propriétés, effectuer des actions (par exemple, un modèle ou une copie). Comme le chemin relatif est renvoyé, vous pouvez facilement recréer l’arborescence de fichiers sur le ou les systèmes cibles.

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

Cela rend les playbooks plus lisibles.

Dag Wieers
la source
Ce n'est pas encore fusionné :-(
Morgan Christiansson
2
Il a été fusionné.
Dag Wieers
Est-il possible de filtrer uniquement les fichiers * .conf?
Andreï
Bien sûr, dans la partie "quand:" vous pouvez écrire une expression qui correspond à vos besoins.
Dag Wieers
1
Le plugin n'est pas lent, c'est le processus de création de modèles et de copie individuelle de chaque fichier qui le ralentit. Mais cela n'a presque rien à voir avec le plugin, le plugin pourrait être utile pour autre chose que la création de modèles ou la copie.
Dag Wieers
3

La commande ci-dessous m'a permis d'effectuer une recherche récursive des fichiers j2 dans les modèles et de les déplacer vers la destination. J'espère que cela aidera quelqu'un à la recherche d'une copie récursive des modèles vers leur destination.

     - 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') }}"
Robin
la source
1

Il est possible de récupérer automatiquement la liste des fichiers du répertoire et de les réitérer ultérieurement.

- 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
la source
Notez la mise en garde standard sur le fractionnement sur une nouvelle ligne - les noms de fichiers peuvent contenir des nouvelles lignes. Une solution plus sûre consiste à utiliser un utilitaire shell qui prend en charge print0, tel que find, puis se scinder \u0000.
Dejay Clayton