Eu tenho uma variável contendo detalhes de máquinas host em minha rede (chamada 'hostlist' - acredito que você chama isso de dicionário, mas não tenho certeza da terminologia. A variável é definida em um arquivo em group_vars/all, então é disponível em todos os manuais (não tenho certeza se isso é importante).
Eu tenho uma peça que gostaria de executar somente se ansible_hostname não for encontrado na lista de nomes de host na lista de hosts. Os nomes de host em hostlist são um dos atributos da variável, mas novamente não tenho certeza se "atributo" é o termo correto...
A lista de hosts é definida como:
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' }
A peça que estou usando para tentar fazer isso funcionar é:
- name: Conditional test
debug:
msg: "ansible_hostname not found in hostlist."
when: ansible_hostname not in hostlist.name
Não tenho certeza da sintaxe exigida na condição ou se o que desejo pode ser alcançado dessa maneira?
Responder1
Presumivelmente, existem maneiras mais elegantes de fazer isso, mas algo assim funciona para mim:
Se o seu arquivo de inventário for assim
host1
host2
host3
host4
Então, um playbook com o seguinte conteúdo só seria executado host4
porque não corresponde à var da lista de hosts:
$ 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
quando chamado assim:
ansible-playbook test.yml
significa que apenas o host4 executa o bloco de tarefas....
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]
Responder2
Opcionalmente, esta condição é mais limpa
when: inventory_hostname not in hostlist|map(attribute="name")|list
Use inventory_hostname
em vez de ansible_hostname
se quiser comparar com a lista de aliases do inventário. VerQual é a diferença entre inventário_hostname e ansible_hostname.
Responder3
uma solução alternativa é (como sugerido no comentário sobre a questão) refatorar a lista de hosts no inventário da seguinte forma:
[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
Então você pode simplificar o manual para executar jogadas contra hosts que não estão em nenhum grupo, usando o ungrouped
grupo especial, que seleciona hosts all
que não estão em nenhum outro grupo:
- hosts: ungrouped
tasks:
- name: only ungrouped
debug:
msg: "host not found in any other group."
ou execute coisas contra esses hosts específicos em grupos...
- 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
saídas
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"
}