Ansible verifica se a variável existe na lista de atributos

Ansible verifica se a variável existe na lista de atributos

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 host4porque 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_hostnameem vez de ansible_hostnamese 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 ungroupedgrupo especial, que seleciona hosts allque 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"
}

informação relacionada