Уведомить обработчик или зарегистрировать переменную ansible при обнаружении изменений в include_role? - PullRequest
0 голосов
/ 27 мая 2018

После долгих поисков я пришел к выводу, что ansible (я использую последнюю стабильную на данный момент версию v2.5.3), скорее всего, не поддерживает регистрацию переменных или уведомлений из операторов include_role и import_role.

Есть похожий вопрос здесь , и предложение в одном из ответов: Each individual task within your include file can register variables, and you can reference those variables elsewhere.

Однако, если я последую этому предложению, мне нужно будет добавить дополнительныененужный код во всех моих включенных ролях, просто потому, что мне может понадобиться обходной путь на специальном сервере.Вещи могут быстро выйти из-под контроля и стать беспорядочными, особенно в случае вложенных включений ролей (т. Е. Когда включенная роль содержит больше включенных ролей).Более того, если я использую роли из ansible-galaxy, я хотел бы придерживаться исходных версий (обрабатывать роли как внешние библиотеки), что означает, что в идеале я бы не хотел менять код роли какне очень интуитивно понятно, что нужно поддерживать вилки всех ролей, которые нужно использовать (в противном случае внешние роли / библиотеки в значительной степени теряют свое значение).

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

Взгляните на следующий конкретный пример того, что я пытаюсь сделать :

У меня есть разделенные задачи, которые я хочу использовать в небольших ролях.В моей роли common у меня есть add-file.yml набор задач, который выглядит следующим образом (roles/common/tasks/add-file.yml):

- name: Copying file "{{ file.src }}" to "{{ file.dest }}"
  copy:
    src: "{{ file.src }}"
    dest: "{{ file.dest }}"
    owner: "{{ file.owner | default(ansible_user_id) }}"
    group: "{{ file.group | default(ansible_user_id) }}"
    mode: "{{ file.mode | default('preserve') }}"
  when:
    file.state is not defined or file.state != 'absent'

- name : Ensuring file "{{ file.dest }}" is absent
  file:
    path: "{{ file.dest }}"
    state: "{{ file.state }}"
  when:
    - file.state is defined
    - file.state == 'absent'

Это в основном универсальная настраиваемая задача для поддержки state: absent для копирования файлов до эта ошибка исправлена.

Затем в другой роли (назовем это setup-XY) я делаю это в файле roles/setup-XY/tasks/main.yml:

- name: Copying X-file
  import_role:
    name: common
    tasks_from: add-file.yml
  vars:
    file:
      state: present
      src: X-file
      dest: /home/user/X-file
      mode: '0640'

- name: Ensuring Yline in Z-file
  lineinfile:
    dest: /etc/default/Z-file
    regexp: '^Yline'
    line: 'Yline=123'

Затем втретья роль (назовем ее z-script). Я хочу что-то вроде этого в файле roles/z-script/tasks/main.yml:

- name: Setup-XY
  include_role:
    name: setup-XY
  register: setupxy

- name: Run Z script if setupXY changed
  shell: /bin/z-script
  when: setupxy.changed

К сожалению, вышеприведенное не работает, поскольку строка register: setupxy регистрирует setupxyпеременная, которая всегда возвращает "changed": false.Если я использую import_role вместо include_role, переменная вообще не регистрируется (остается неопределенной).

Обратите внимание, что в роли z-script я хочу запускать команду оболочки /bin/z-script всякий раз, когдав роли setup-XY обнаружено любое изменение, т. е. в случае изменения X-file или Z-file, и в действительности у меня может быть гораздо больше задач в роли setup-XY.

Более того, обратите вниманиечто z-script не связан с ролью setup-XY (например, z-script должен запускаться только на конкретном проблемном сервере), поэтому код для выполнения z-script в идеале не следует отправлять вместес (и загрязняют) ролью setup-XY.Посмотрите на setup-XY как внешнюю / восходящую роль в этом случае.

...