Как я могу определить участника инвентаря, который имеет определенный атрибут? - PullRequest
2 голосов
/ 19 сентября 2019

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

фрагмент: hosts.yml

  dbservers:
       hosts:
        pg01:
         ansible_host: pg01.domain.com
         master_slave: master
        pg02:
         ansible_host: pg02.domain.com
         master_slave: slave

Я хочу разрешить pg01основываясь на том факте, что переменная master_slave установлена ​​на «master», так что я могу вызвать такую ​​роль:

      - name: Do something
        include_role:
         name: a.database.role.to.run.on.master
        vars:
          master_database_host: {{ something that resolves to pg01 }}

Как я могу разрешить соответствующий хост из инвентаря?

Ответы [ 4 ]

4 голосов
/ 19 сентября 2019

Вы можете использовать комбинацию фильтров для извлечения необходимого хоста:

tasks:
- debug:
    msg: '{{groups["group_name"] | map("extract", hostvars) | selectattr("master_slave", "equalto", "master") | map(attribute="inventory_hostname") | list}}'

Шаг за шагом:

groups["group_name"] - это список всеххосты в группе group_name.

map("extract", hostvars) принимают hostvars, словарь, сопоставляющий хост с их переменными, и извлекают хосты, которые находятся в group_name (то есть groups["group_name"]).В результате получается список, содержащий хосты в group_name, сопоставленные с их переменными.

selectattr("master_slave", "equalto", "master") выбирает все хосты, которые имеют атрибут master_slave, равный master.В результате получается список со всеми хостами, которые являются мастерами, сопоставленными с их переменными.

map(attribute="inventory_hostname") принимает список в качестве входных данных и возвращает атрибут inventory_hostname каждого элемента.В результате получается список со всеми хостами, которые являются мастерами.

2 голосов
/ 19 сентября 2019

Игра ниже (с json_query)

- hosts: dbservers
  tasks:
    - set_fact:
        master_database_host: "{{ groups['dbservers']|
                                  map('extract',hostvars)|
                                  list|
                                  json_query('[?master_slave==`master`].inventory_hostname')|
                                  first }}"
    - debug:
        var: master_database_host

дает

ok: [pg02] => {
    "master_database_host": "pg01"
}
ok: [pg01] => {
    "master_database_host": "pg01"
}
2 голосов
/ 19 сентября 2019

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

  - name: Do something
    include_role:
     name: a.database.role.to.run.on.master
    vars:
      master_database_host: "{{ hostvars['pg01']['ansible_host'] if \"{{ hostvars['pg01']['master_slave'] }}\" == 'master' else 'default value goes here'}}"

Убедитесь, что используется условное экранирование, чтобы условные операторы работали.

Причина, по которой это работает, так как ansible внутренне использует python для выполнения вещейэто способ использовать троичный оператор в Python.

1 голос
/ 19 сентября 2019

Вы также можете генерировать динамические группы на основе статуса ведущего / подчиненного:

---
 - name: Play to create dynamic groups
   hosts: dbservers
   gather_facts: false
   tasks:
    - name: Create groups based on variable master_slave
      group_by:
        key: "database-{{ hostvars[inventory_hostname]['master_slave'] }}"

 - name: Play to use the dynamic group database-master
   hosts: database-master
   gather_facts: false
   tasks:
    - name: Show hosts in group
      debug:
        msg: "This is {{ inventory_hostname }} from the dynamic database-master group."

При первом воспроизведении используются все серверы db и создаются динамические группы на основе переменной master_slave.Динамические группы:

  • database-master, содержащие pg01
  • database-slave, содержащие pg02

Во втором воспроизведении используется одна из динамически созданных групп.

Для использования group_by используемая переменная должна существовать для всех используемых хостов.

Эта концепция лучше всего работает с автоматической переменной, собираемой настройкой ansibles, например ansible_distribution, для создания динамических групп на основеДистрибутив (Debian, Redhat, Ubuntu ...) или дистрибутивные версии, использующие ansible_distribution_version.

...