Ansible prüft, ob die Variable in der Attributliste vorhanden ist

Ansible prüft, ob die Variable in der Attributliste vorhanden ist

Ich habe eine Variable mit Details zu Host-Rechnern in meinem Netzwerk (genannt „Hostlist“ – ich glaube, Sie nennen das ein Wörterbuch, aber ich bin mir bei der Terminologie nicht sicher. Die Variable ist in einer Datei in group_vars/all definiert, also ist sie in allen Playbooks verfügbar (ich bin nicht sicher, ob das wichtig ist).

Ich habe ein Spiel, das ich nur ausführen möchte, wenn ansible_hostname nicht in der Liste der Hostnamen in der Hostliste gefunden wird. Die Hostnamen in der Hostliste sind eines der Attribute der Variable, aber ich bin mir wieder nicht sicher, ob „Attribut“ der richtige Begriff ist …

Hostlist wird wie folgt definiert:

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' }

Ich versuche, dies durch folgendes Spiel zum Laufen zu bringen:

- name: Conditional test
  debug:
    msg: "ansible_hostname not found in hostlist."
  when: ansible_hostname not in hostlist.name

Ich bin mir nicht sicher, welche Syntax für die Bedingung erforderlich ist oder ob mein Ziel auf diese Weise erreicht werden kann.

Antwort1

Es gibt vermutlich elegantere Möglichkeiten, dies zu tun, aber so etwas funktioniert für mich:

Wenn Ihre Inventardatei so aussieht

host1
host2
host3
host4

Dann würde ein Playbook mit dem folgenden Inhalt nur ausgeführt, host4weil es in der Hostlist-Variable nicht übereinstimmt:
$ 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

wenn es so aufgerufen wird:

ansible-playbook test.yml

bedeutet, dass nur Host4 den Aufgabenblock ausführt …

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]

Antwort2

Optional ist dieser Zustand sauberer

    when: inventory_hostname not in hostlist|map(attribute="name")|list

Verwenden Sie inventory_hostnameanstelle von ansible_hostname, wenn Sie mit der Liste der Aliase des Inventars vergleichen möchten. SieheWas ist der Unterschied zwischen inventory_hostname und ansible_hostname.

Antwort3

eine alternative Lösung besteht (wie im Kommentar zur Frage vorgeschlagen) darin, die Hostliste wie folgt in das Inventar umzugestalten:

[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

Anschließend können Sie das Playbook vereinfachen, um Spiele gegen Hosts auszuführen, die sich in keiner Gruppe befinden. Dazu verwenden Sie die spezielle ungroupedGruppe, die Hosts auswählt, alldie sich in keiner anderen Gruppe befinden:

- hosts: ungrouped
  tasks:
    - name: only ungrouped
      debug:
        msg: "host not found in any other group."

oder führen Sie Dinge gegen diese bestimmten Hosts in Gruppen aus …

- 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

Ausgänge

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"
}

verwandte Informationen