ansible: выполнить задачу несколько раз на одном и том же хосте, используя переменные из другого

Вопрос или проблема

Новый в ansible, не могу найти ссылку на мою проблему, которая не кажется такой уж редкой..

У меня есть два хоста в одной группе, каждый из которых имеет свои переменные, скажем:

[myHosts]
host1  a=1  b=10
host2  a=2  b=20

Теперь у меня есть задача, которая должна выполняться дважды только на host1, один раз с переменными host1, а во второй раз со значением a из host1 и b из host2.
Если я напишу это так:

- role: my_role
      vars:
        a_val: {{ a }}
        b_val: {{ b }}
      loop: "{{ groups['myHosts'] }}"
      when: inventory_hostname in groups['myHosts'][0]

Я получаю a_val и b_val, заполненные только значениями host1 (что хорошо для a_val, но не для b_val).

Я знаю, что, похоже, нет причин, по которым я не могу просто вызвать одну и ту же задачу дважды, ссылаясь на правильное значение b с помощью каких-то волшебных переменных ansible (hostvars[groups['myHosts'][1]]['b'] сработает, например), но хостов может стать 10 завтра и это будет раздражать (в этом случае условие when все равно будет хорошим, так как все всегда будет выполняться там).

Как я могу обобщить, чтобы b_val заполнился правильным значением?

В: “Задача, которая должна выполняться дважды только на host1, один раз с переменными host1, а во второй раз со значением a из host1 и b из host2.”

О: hostvars позволяет получить доступ к переменным для другого хоста. Например, плей

- hosts: host1
  tasks:
    - debug:
        msg: "a:{{ item.a }} b:{{ item.b }}"
      loop:
        - "{'a': {{ a }}, 'b': {{ b }} }"
        - "{'a': {{ a }}, 'b': {{ hostvars['host2'].b }} }"

выдает

ok: [host1] => (item={'a': 1, 'b': 10}) => {
    "msg": "a:1 b:10"
}
ok: [host1] => (item={'a': 1, 'b': 20}) => {
    "msg": "a:1 b:20"
}

Это то, что мне было нужно: https://stackoverflow.com/a/32336359/827818

Я сделал отдельный список вот так:

bs_list:
  host1:
    b: val1
  host2:
    b: val2

включенный с помощью pre_tasks, а потом

- debug: 
    msg: "{{ item.value.b }}"
  with_dict: "{{ bs_list }}"
  when: inventory_hostname in groups['myHosts'][0]

Ответ или решение

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

Задача

Вы хотите выполнить задачу дважды на host1, используя сначала переменные самого хоста, а затем используя переменную a из host1 и переменную b из host2. Ваша текущая реализация не позволяет правильно получить переменную b, так как она ссылается только на host1.

Решение

1. Использование магических переменных

Ansible предоставляет мощные возможности обращения к переменным с помощью hostvars. Это позволяет вам обращаться к переменным других хостов из любого места в вашем произведении.

Вы можете использовать следующую структуру:

- hosts: host1
  tasks:
    - name: Выполнение задачи с переменными host1
      debug:
        msg: "a: {{ a }} b: {{ b }}"

    - name: Выполнение задачи с переменной `a` из host1 и `b` из host2
      debug:
        msg: "a: {{ a }} b: {{ hostvars['host2']['b'] }}"

2. Использование цикла для генерации данных

Если вам нужно более общее решение, которое может быть легко изменено для большего количества хостов, вы можете использовать список для задания переменных и цикл. Например:

- hosts: host1
  vars:
    other_hosts: "{{ groups['myHosts'] | difference([inventory_hostname]) }}"
  tasks:
    - name: Выполнение задачи с переменными host1
      debug:
        msg: "a: {{ a }} b: {{ b }}"

    - name: Выполнение задачи с использованием переменной b из другого хоста
      debug:
        msg: "a: {{ a }} b: {{ hostvars[item]['b'] }}"
      loop: "{{ other_hosts }}"

Описание кода

  1. Переменные хостов:

    • Первая задача выводит значения переменных a и b непосредственно из host1.
  2. Цикл по другим хостам:

    • Вторая задача через цикл loop обращается к hostvars[item]['b'], где item — это каждый хост из списка других хостов (other_hosts).

Заключение

Таким образом, используя hostvars и циклы, вы можете легко адаптировать ваши задачи для работы с переменными из разных хостов. Это позволит вам использовать гибкое и расширяемое решение, которое будет работать независимо от количества хостов в группе. Убедитесь, что вы правильно настроили инвентаризацию и что все переменные доступны для ваших задач.

SEO элементы

Этот ответ охватывает:

  • Особенности Ansible по работе с переменными.
  • Примеры кода для практического применения.
  • Объяснения для понимания структуры задач Ansible.

Таким образом, вы получаете не только инструкцию по решению вашей проблемы, но и полезные советы по расширению этой логики в будущем.

Оцените материал
Добавить комментарий

Капча загружается...