У меня есть переменная, содержащая сведения о хост-машинах в моей сети (называемая «список хостов» - я полагаю, вы называете это словарем, но я не уверен в терминологии. Переменная определена в файле в group_vars / all, поэтому она доступно во всех плейбуках (не уверен, что это важно).
У меня есть игра, которую я хотел бы запустить, только если ansible_hostname не найден в списке имен хостов в hostlist. Имена хостов в hostlist являются одним из атрибутов переменной, но опять же я не уверен, что термин «атрибут» правильный ...
Hostlist определяется как:
hostlist:
- { name: 'host1', ip_addr: '192.168.2.31', hostgrp: 'physical_workstation' }
- { name: 'host2', ip_addr: '192.168.2.32', hostgrp: 'physical_workstation' }
- { name: 'host3', ip_addr: '192.168.2.33', hostgrp: 'virtual_machine' }
Чтобы заставить это работать, я использую следующую игру:
- name: Conditional test
debug:
msg: "ansible_hostname not found in hostlist."
when: ansible_hostname not in hostlist.name
Я не уверен в синтаксисе, требуемом в условии, или можно ли таким образом достичь того, чего я хочу?
При желании это состояние чище
when: inventory_hostname not in hostlist|map(attribute="name")|list
Использовать inventory_hostname
вместо того ansible_hostname
если вы хотите сравнить со списком псевдонимов инвентаря. Видеть В чем разница между inventory_hostname и ansible_hostname.
По-видимому, есть более элегантные способы сделать это, но у меня работает что-то вроде этого:
Если ваш файл инвентаря выглядит так
host1
host2
host3
host4
Тогда playbook со следующим содержанием будет запускаться только против host4
потому что он не соответствует в hostlist var:
$ cat test.yml
- hosts: all
vars:
hostlist:
- { name: 'host1', ip_addr: '192.168.2.31', hostgrp: 'physical_workstation' }
- { name: 'host2', ip_addr: '192.168.2.32', hostgrp: 'physical_workstation' }
- { name: 'host3', ip_addr: '192.168.2.33', hostgrp: 'virtual_machine' }
tasks:
- name: Conditional test
debug:
msg: "ansible_hostname not found in hostlist."
when: hostlist|selectattr("name", "equalto", ansible_hostname)|list|length == 0
при таком вызове:
ansible-playbook test.yml
означает, что только host4 выполняет блок задач ....
PLAY [all] *************************************************
TASK [Gathering Facts] *************************************
ok: [host1]
ok: [host2]
ok: [host3]
ok: [host4]
TASK [debug] ***********************************************
ok: [host4] => {
"msg": "hostname not in hostlist name list"
}
skipping: [host1]
skipping: [host2]
skipping: [host3]
альтернативное решение (как предлагается в комментарии к вопросу) состоит в том, чтобы преобразовать список хостов в инвентарь следующим образом:
[physical_workstation]
host1 ansible_host=192.168.2.31
host2 ansible_host=192.168.2.32
[virtual_machine]
host3 ansible_host=192.168.2.33
[all]
host4 ansible_host=192.168.2.34
Затем вы можете упростить игру, чтобы запускать игры против хостов, которые не находятся в группах, используя специальный ungrouped
группа, которая выбирает хосты из all
которые не входят ни в одну другую группу:
- hosts: ungrouped
tasks:
- name: only ungrouped
debug:
msg: "host not found in any other group."
или запустить что-то против этих конкретных хостов в группах ...
- hosts: physical_workstation:virtual_machine
tasks:
- name: only in specified groups
debug:
msg: |
This will run on machines that are in groups:
physical_workstation or virtual_machine
выходы
PLAY [ungrouped] ***********************************************
TASK [only ungrouped] ******************************************
ok: [host4] => {
"msg": "host not found in any other group."
}
PLAY [physical_workstation:virtual_machine] ********************
TASK [only in specified groups] ********************************
ok: [host1] => {
"msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}
ok: [host2] => {
"msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}
ok: [host3] => {
"msg": "This will run on machines that are in groups:\nphysical_workstation or virtual_machine"
}