Wie wähle ich alle Hosts außer dem Bestandshostnamen aus einer Gruppe aus?

Wie wähle ich alle Hosts außer dem Bestandshostnamen aus einer Gruppe aus?

Ich habe eine Gruppe mit zwei Hosts. Ich möchte eine Aufgabe an den Host delegieren, der nicht der aktuelle Host ist.

Das Folgende ergibt keine Übereinstimmung und gibt lediglich eine Liste meiner ersten beiden Hosts zurück.

  - debug: msg="{{ groups['web-servers'] | select('match', '^(?!\{\{\ inventory_hostname\ \}\}$).+') | list }}"

Ich glaube, das Problem liegt in der Flucht, aber ich komme nicht dahinter.

Antwort1

Eine Möglichkeit wäre die Verwendung vonUnterschiedFilter. Unten sehen Sie ein Beispiel für die Verwendung des Filters

shell> cat test-difference-01.yml
- hosts: localhost
  gather_facts: no
  vars:
    web_servers:
      - web-server-01
      - web-server-02
      - web-server-09
    inventory_hostname:
      - web-server-02
  tasks:
    - set_fact:
        delegate_to_hosts: "{{ web_servers|difference(inventory_hostname) }}"
    - debug:
        msg : "{{ delegate_to_hosts }}"
shell> ansible-playbook test-difference-01.yml | grep -A 3 msg
    "msg": [
        "web-server-01", 
        "web-server-09"
    ]

Q:"Gruppe von zwei Hosts ... delegieren Sie eine Aufgabe an denjenigen, der nicht der aktuelle Host ist"

Angesichts des Inventars

shell> cat hosts
[webservers]
web-server-01
web-server-02

Das Spielbuch

- hosts: webservers
  tasks:
    - debug:
        msg: "{{ inventory_hostname }} {{ item }}"
      loop: "{{ groups.webservers|difference([inventory_hostname]) }}"
      delegate_to: "{{ item }}"

gibt (gekürzt)

ok: [web-server-01 -> web-server-02] => (item=web-server-02) => 
  msg: web-server-01 web-server-02
ok: [web-server-02 -> web-server-01] => (item=web-server-01) => 
  msg: web-server-02 web-server-01

Der Code kann verallgemeinert werden durch Ausführen aufalleGastgeber aufgeführt inansible_play_hosts_all

- hosts: all
  tasks:
    - debug:
        msg: "{{ inventory_hostname }} {{ item }}"
      loop: "{{ ansible_play_hosts_all|difference([inventory_hostname]) }}"
      delegate_to: "{{ item }}"

Antwort2

Sie müssen keinen regulären Ausdruck mit negativem Lookahead angeben. Verwenden Sie stattdessen dierejectFilter.

equaltoDarüber hinaus müssen Sie bei „Test“ die Zeichenfolge nicht in ^„und“ einschließen $:

- debug:
    msg: "{{ groups['web-servers'] | reject('equalto', inventory_hostname) | list }}"

Antwort3

Ich denke, das Problem liegt an der Variablensubstitution (oder dem Fehlen derselben) im Regex-Muster. Sie können das Muster separat definieren und es an den Filter übergeben (beachten Sie, dass ich Ihren Regex ein wenig geändert habe):

- set_fact: pattern="^(?!{{ inventory_hostname }}).+$"
- debug: msg="{{ groups['web-servers'] | select('match', pattern) | list }}"

Ergebnis:

TASK [debug : debug] ******************************************
ok: [foo] => {
    "msg": [
        "bar",
        "baz"
    ]
}
ok: [bar] => {
    "msg": [
        "foo",
        "baz"
    ]
}
ok: [baz] => {
    "msg": [
        "foo",
        "bar"
    ]
}

verwandte Informationen