Ansible: применение шаблонов ролей иерархически
Я планирую использовать Ansible для управления довольно большим набором серверов Linux с большим разнообразием среди них.
Хосты будут сгруппированы в роли с иерархией между ними, есть common
роль, от которой зависит каждый другой, дочерние роли, которые зависят от common
и могут быть роли внуков, которые зависят от них, без ограничений по глубине зависимости.
common
|___ role1
|___ role2
|___ role3
|___ role3.1
Каждая роль имеет свое собственное подмножество шаблонов для файлов конфигурации системы.
roles/
common/
templates/
etc/
hosts
resolv.conf
tasks/
main.yml
system-settings.yml # imported in main.yml
role1/
templates/
etc/
hosts # role-specific version, overrides 'common'
httpd/
conf/
httpd.conf
tasks/
main.yml
system-settings.yml # imported in main.yml
role2/
role3/
role3.1/
Сложность в том, что я хотел бы применять эти шаблоны иерархически, подобно тому, как Ansible разрешает переменные области. Таким образом, для данной дочерней роли применяется наиболее конкретная версия файла шаблона, если шаблон в этой роли не существует, тогда примените версию родительского элемента, выполняя поиск до корневого уровня.
Я (вроде) достиг этого, поставив в system-settings.yml
для каждой роли:
- name: Create directories
file:
path: /{{ item.path }}
state: directory
mode: '{{ item.mode }}'
with_filetree: templates/
when: item.state == 'directory'
- name: Template files
template:
src: '{{ item.src }}'
dest: /{{ item.path }}
mode: '{{ item.mode }}'
with_filetree: templates/
when: item.state == 'file'
- name: Recreate symlinks
file:
src: '{{ item.src }}'
dest: /{{ item.path }}
state: link
force: yes
mode: '{{ item.mode }}'
with_filetree: templates/
when: item.state == 'link'
Это работает, но, к сожалению, он применяет все шаблоны родительской роли, а затем все шаблоны дочерней роли. Это пустая трата работы и опасно, если выполнение playbook по какой-либо причине прерывается, поскольку на хостах могут остаться общие версии системных файлов.
Итак, для приведенного выше примера дерева, при применении role1
группе хостов Ansible:
- относится
/etc/hosts
а также/etc/resolv.conf
отcommon
роль - относится
/etc/hosts
а также/etc/httpd/conf/httpd.conf
отrole1
роль
Но я хочу это сделать:
- применять
/etc/resolv.conf
отcommon
роль - применять
/etc/hosts
отrole1
роль (самая конкретная версия) - применять
/etc/httpd/conf/httpd.conf
отrole1
роль
Файлы шаблонов не должны быть конкретно перечислены в задачах / книгах воспроизведения из-за накладных расходов на управление при добавлении нового файла или версии для конкретной роли для переопределения универсального файла, который мы не хотим менять в любых книгах воспроизведения или других конфигурациях.
Это достижимо с Ansible?
Я вижу возможное решение с использованием внешних скриптов (как описано в https://docs.ansible.com/ansible/2.4/playbooks_loops.html), но я Я не уверен, как передать иерархию ролей в сценарий.
1 ответ
Мои мысли:
Первый выбор: измените "общие" файловые задачи на "общие" обработчики. Причина, по которой я выбрал обработчики, заключается в том, что мы можем условно включать обработчики. Также у нас есть роли до / после обработки. Сообщите, что все задачи, которые не выполняются в роли, и что должны быть выполнены, могут быть обработчиками до ролей.
Второй вариант: условно включайте задачи, я думаю, что нужно приложить много усилий, чтобы прикрепить теги к включенным файлам. Например:
---
-name: task inclusion
Hosts: localhost
Gether_facts: false
Tasks:
Include: common.yaml
When: item | bool
A_list:
-true
-false
Надеюсь это поможет.
С уважением, Судхакар