Развертывание папки с файлами шаблонов с использованием ansible


47

Есть ли простой способ развернуть папку, полную шаблона .j2, в папку linux, используя то же имя, что и шаблон, но без расширения .j2, вместо использования модуля шаблона для каждого файла?

Прямо сейчас у меня есть длинный список:

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

Ответы:


68

Вы можете использовать, with_fileglobчтобы получить список файлов из вашего каталога шаблонов и использовать фильтры для удаления расширения j2, как это ..

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

11
Примечание with_fileglobвсегда работает с files/, вы можете добраться до шаблонов с ../templates/mytemplate/*. stackoverflow.com/a/27407566/1695680
ThorSummoner

2
Спасибо, это очень полезно. Я обнаружил, что мне пришлось использовать две обратные косые черты, чтобы избежать буквального периода в функции regex_replace. Возможно, потому что у меня была вся часть шаблона dest в двойных кавычках, чтобы я мог использовать формат YAML для определения задачи (который я предпочитаю формату с одной строкой).
Тони Чезаро

1
это предполагает, что только файлы находятся в папке шаблонов, если вам нужно поддерживать как каталоги, так и файлы в папке шаблонов, тогда вам нужно with_filetree - см. stackoverflow.com/questions/41667864/…
danday74

Примечание, которое regex_replaceдолжно совпадать в конце строки \.j2$для случаев, когда шаблон может существовать внутри имени файла.
Бретт Райан

20

Майкл ДеХан (создатель Ansible) сделал пост на CoderWall, в котором говорится об очень похожей проблеме. Вы можете настроить и расширить его в соответствии с вашими потребностями (например, разрешения и права собственности). Соответствующая часть поста здесь:


Это можно упростить с помощью " with_items" и одного notifyоператора. Если какая-либо из задач изменится, служба будет уведомлена точно так же, как она должна перезапуститься в конце прогона 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

Обратите внимание, что поскольку у нас есть задачи, которые принимают более одного уникального аргумента, мы не просто говорим « item» в template:строке «», но используем with_itemsпеременную хеша (словаря). Вы также можете сделать это немного короче, используя списки, если хотите. Это стилистическое предпочтение:

 - 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

Конечно, мы могли бы также определить список, по которому вы шли, в другом файле, например, в groupvars/webserversфайле " ", чтобы определить все переменные, необходимые для webserversгруппы, или в файле YAML, загруженном из varsfilesдирективы " " внутри книги воспроизведения. Посмотри, как это можно очистить, если мы это сделаем.

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

5
Более простой способ может быть написать template: src=templates/{{item}}.j2 dest=/etc/splat/{{item}}.conf, а затем использовать простой список элементов:with_items: - foo - bar
Итан

Это на самом деле выглядит неправильно сейчас. Правильная линия шаблона будет template: src={{item.src}} dest={{item.dest}}(то есть, ${var}но не скорее {{var}})
Фабиано Франческони

@FabianoFrancesconi обновлен.
Mxx

9

Ответ Рассела работает, но нуждается в улучшении

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

Едва все $ должны идти, поскольку это было неправильное регулярное выражение в regex_replace. Во-вторых, все файлы должны быть в каталоге файлов, а не в каталоге шаблонов.


4
Добро пожаловать в сбой сервера! Ваш ответ предполагает, что реальное решение вопроса доступно через предыдущий ответ, поэтому было бы более уместным в качестве редактирования этого ответа. Пожалуйста, рассмотрите возможность удаления вашего текущего ответа и предложения изменить ответ Рассела.
Пол

7

Я написал плагин поиска файлового дерева, который может помочь с действиями над деревьями файлов.

Вы можете просматривать файлы в дереве файлов и на основе свойств файлов выполнять действия (например, шаблон или копирование). Поскольку возвращается относительный путь, вы можете с легкостью воссоздать файловое дерево в целевых системах.

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

Это делает для более читаемых книг.


Это еще не было объединено :-(
Морган Кристиансон

2
Это было объединено.
Даг Вирс

Есть ли способ фильтрации, скажем, только * .conf файлов?
Андрей

Конечно, в части «когда:» вы можете написать выражение, которое соответствует вашим потребностям.
Даг Вирс

1
Плагин не медленный, процесс создания и копирования каждого файла по отдельности делает его медленным. Но это вряд ли имеет какое-либо отношение к плагину, плагин может быть полезен для других вещей, чем шаблонов или копирования.
Даг Вирс

3

Следующая команда сработала для меня, чтобы сделать рекурсивный поиск файлов j2 в шаблонах и переместить его в место назначения. Надеюсь, это поможет кому-то, ищущему рекурсивную копию шаблонов по назначению.

     - 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

Существует возможность автоматически получать список актуальных файлов из каталога и повторять их впоследствии.

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

Обратите внимание на стандартное предупреждение о разделении на новую строку - имена файлов могут содержать новые строки. Более безопасным решением является использование утилиты оболочки, которая поддерживает print0, например find, и затем разделяется на \u0000.
Деджей Клейтон,
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.