2016-12-20 8 views
4

Я имею переменный анзибль, содержащий список веб-сервера (все на тот же хост):Run анзибль обработчики на основе измененных результатов несколько петель

servers: 
    - foo 
    - bar 
    - baz 

И задачу, которая меняет свои файлы конфигурация и регистров результаты в переменной:

- name: create server configs 
    template: ... 
    with_items: "{{ servers }}" 
    notify: restart changed servers 
    register: servers_changed 

и обработчик, который перезапускает только серверы, которые изменены, когда эта задача выполняется:

- name: restart changed servers 
    command: restart-my-server {{ item.item.name }} 
    when: item.changed 
    with_items: "{{ servers_changed.results }}" 

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

Я могу регистрировать разные переменные в каждой задаче, но тогда мне нужен другой обработчик для каждого из них. Это будет беспорядочно. Есть ли способ лучше?

ответ

0

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

вары:

servers: 
- name: server1 
    port: 1000 
- name: server2 
    port: 1001 

задачи:

- name: create server configs 
    template: ... 
    with_items: "{{ servers }}" 
    notify: restart changed servers 
    register: servers_changed 

- name: remember which servers need to restart 
    set_fact: 
    restart_servers: "{{ restart_servers | default([]) + [item.item.name] }}" 
    when: item.changed 
    with_items: "{{ servers_changed.results }}" 

погрузчики:

- name: restart changed servers 
    command: restart-my-server {{ item.name }} 
    when: item.name in restart_servers | default([]) 
    with_items: "{{ servers }}" 

Недостаток заключается в том, что после каждой задачи, которые могут вызвать перезагрузку, вам нужна вторая задача call set_fact на основе измененных серверов.

Преимущество в том, что это легко понять и позволяет избежать дублирования обработчиков или повторных перезапусков.

+0

Прохладный. Но почему бы не использовать 'with_items:" {{restart_servers}} "' непосредственно в обработчике, исключив это 'when' ...? –

+1

@WojciechKaczmarek Я думаю, я упростил вещи слишком много для моего примера. В моей реальной настройке 'servers' - это список dicts с подробностями о каждом сервере, но' restart_servers' - это всего лишь список имен, идентифицирующих каждый сервер. Вместо этого вы можете перехватывать обработчик вместо 'restart_servers', но цикл над серверами позволяет ему получить доступ к сведениям о каждом перезапуске сервера. В качестве примера у меня есть мой обработчик, который смотрит на номер порта каждого сервера и дождитесь, пока он станет открытым до продолжения. –

+0

Я обновил пример. –

3

Использование servers_changed в качестве составного списка и сцепить результаты каждой задачи:

- name: create server configs 
    template: ... 
    with_items: "{{ servers }}" 
    notify: restart changed servers 
    register: servers_changed_now 

- set_fact: 
    servers_changed: "{{ servers_changed | default([]) | union(servers_changed_now.results|default([]) }}" 

и

- name: restart changed servers 
    command: restart-my-server {{ item.item.name }} 
    when: item.changed 
    with_items: "{{ servers_changed }}" 
+1

В результате я создал настраиваемый фильтр для использования в set_fact, который объединяет зарегистрированные переменные, но игнорирует дублированные серверы (чтобы не перезапускать сервер более одного раза). –

+0

На самом деле здесь нет необходимости в настраиваемых фильтрах, я обновил ответ, чтобы обрабатывать пустые списки и дублировать записи. – techraf

+0

Я не думаю, что это устранит дубликаты серверов, так как вам нужно искать в item.item, чтобы найти имя сервера. –