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:

  1. относится /etc/hosts а также /etc/resolv.conf от common роль
  2. относится /etc/hosts а также /etc/httpd/conf/httpd.conf от role1 роль

Но я хочу это сделать:

  1. применять /etc/resolv.conf от common роль
  2. применять /etc/hosts от role1 роль (самая конкретная версия)
  3. применять /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

Надеюсь это поможет.

С уважением, Судхакар

Другие вопросы по тегам