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, host4
weil 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_hostname
anstelle 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 ungrouped
Gruppe, die Hosts auswählt, all
die 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"
}