Ansible: Ermittelt die IP-Adresse des aktuellen Zielhosts

100

Wie erhalten Sie die IP-Adresse des aktuellen Hosts in einer Rolle?

Ich weiß, dass Sie die Liste der Gruppen, zu denen der Host gehört, und den Hostnamen des Hosts abrufen können, aber ich kann keine Lösung finden, um die IP-Adresse abzurufen.

Sie können den Hostnamen mithilfe von {{inventory_hostname}}und die Gruppe mithilfe von abrufen{{group_names}}

Ich habe Dinge wie {{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }} und ausprobiertip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

SJC
quelle

Antworten:

124

Eine Liste aller Adressen wird in einem Fakt gespeichert ansible_all_ipv4_addresses, eine Standardadresse in ansible_default_ipv4.address.

---
- hosts: localhost
  connection: local
  tasks:
    - debug: var=ansible_all_ipv4_addresses
    - debug: var=ansible_default_ipv4.address

Dann werden jeder Netzwerkschnittstelle Adressen zugewiesen ... In solchen Fällen können Sie alle Fakten anzeigen und diejenige finden, die den Wert hat, den Sie verwenden möchten.

Techraf
quelle
Wie zeigen Sie alle Flags an?
SJC
1
Können Sie alle Flags innerhalb einer Aufgabe auflisten?
SJC
2
@ SJC Flags? Du meinst Fakten, richtig? Ja, setup:Modul ausführen mit register: allfactsund anzeigen mit- debug: var=allfacts
techraf
4
Der Wert von gather_factsmuss sein, truedamit dies funktioniert. Es ist standardmäßig wahr, aber man kann es auf falsch setzen, wenn die Informationen über die Hosts nicht benötigt werden.
Shshnk
1
@poige Es ist möglicherweise falsch, wenn Sie wie Sie eine neue Frage stellen.
Techraf
69

Sie können die IP-Adresse von hostvars, dict ansible_default_ipv4und key erhaltenaddress

hostvars[inventory_hostname]['ansible_default_ipv4']['address']

bzw. IPv6-Adresse

hostvars[inventory_hostname]['ansible_default_ipv6']['address']

Ein Beispiel für ein Spielbuch:

---
- hosts: localhost
  tasks:
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv6']['address']
Pasi H.
quelle
Dies kann in einigen Fällen fehlschlagen, siehe: medium.com/opsops/…
RafalS
25

Sie können in Ihrer template.j2 {{ ansible_eth0.ipv4.address }}genauso verwenden, wie Sie es verwenden {{inventory_hostname}}.

ps: Weitere Informationen zum Sammeln von Informationen zu Fernbedienungshosts mit glaubwürdigen GATHERS-FAKTEN finden Sie im folgenden Blogpost .

Ich hoffe, es wird eines Tages jemandem helfen

Orsius
quelle
13
Sei besonders vorsichtig. Heutzutage ist die Standardnetzwerkschnittstelle nicht immer 'eth0'. Es nannte manchmal ens3oder enp2s0und solche Dinge. Sie haben einfach bessere Wetten, wenn Sie verwenden ansible_default_ipv4und wenn es nicht funktioniert, dann wechseln Sie zurück und suchen Sie nach vernünftigen Standardeinstellungen.
Gabor Garami
4
Dies hat wahrscheinlich in der Vergangenheit funktioniert, aber mit Ansible 2.7 ist diese Variable undefiniert.
Dirk
5

Wenn Sie die externe öffentliche IP- Adresse möchten und sich in einer Cloud-Umgebung wie AWS oder Azure befinden, können Sie das Modul ipify_facts verwenden :

# TODO: SECURITY: This requires that we trust ipify to provide the correct public IP. We could run our own ipify server.
- name: Get my public IP from ipify.org
  ipify_facts:

Dadurch wird die öffentliche IP in die Variable eingefügt ipify_public_ip.

Simon Woodside
quelle
Das funktioniert nicht immer. Für mich ist die ipify_public_ipVariable leer
Davide
2
Bei AWS ist inventar_hostname die IP-Adresse.
Berend de Boer
Dieses Plugin kann unter bestimmten Umständen funktionieren. Wenn Sie hinter einem NAT auf das Internet zugreifen, funktioniert es nicht. Grundsätzlich funktioniert dies, wenn die Server für das Internet zugänglich sind und auf die Website ipify.org zugreifen können, um ihre externe IP beim Zugriff auf die Website aufzulösen.
Slm
1
@BerenddeBoer Falsch. inventory_hostnameist was auch immer im Inventar eingestellt ist. Es könnte ein Hostname sein, wie in festgelegt .ssh/config.
Teresa e Junior
@slm wie gesagt, wenn Sie nach der externen öffentlichen IP suchen. Wenn Sie sich hinter einem NAT befinden, verfügen Sie nicht über eine externe öffentlich zugängliche IP, sodass Sie diese Methode nicht verwenden würden.
Simon Woodside
4

Eine andere Möglichkeit, öffentliche IP zu finden, wäre die Verwendung des uriModuls:

    - name: Find my public ip
      uri: 
        url: http://ifconfig.me/ip
        return_content: yes
      register: ip_response

Ihre IP wird in sein ip_response.content

Chava
quelle
Eine andere Service-URL, die das gleiche zurückgibt, ist:https://ipecho.net/plain
Paul Parker
@PaulParker ipecho.net/plain scheint KO oder fragen Sie API-Token ... ifconfig.me besseren und stabilen Service seit Jahren: +1
Bastien
Ich wurde nie nach einem API-Token gefragt. Ich kann nicht mit der Konsistenz des Dienstes sprechen, ich habe ihn nicht überwacht, aber er hat mich nie im Stich gelassen.
Paul Parker
2

Einfacher Debug-Befehl:

ansible -i inventory/hosts.yaml -m debug -a "var=hostvars[inventory_hostname]" all

Ausgabe:

"hostvars[inventory_hostname]": {
    "ansible_check_mode": false, 
    "ansible_diff_mode": false, 
    "ansible_facts": {}, 
    "ansible_forks": 5, 
    "ansible_host": "192.168.10.125", 
    "ansible_inventory_sources": [
        "/root/workspace/ansible-minicros/inventory/hosts.yaml"
    ], 
    "ansible_playbook_python": "/usr/bin/python2", 
    "ansible_port": 65532, 
    "ansible_verbosity": 0, 
    "ansible_version": {
        "full": "2.8.5", 
        "major": 2, 
        "minor": 8, 
        "revision": 5, 
        "string": "2.8.5"
    }, 

Host-IP-Adresse abrufen:

ansible -i inventory/hosts.yaml -m debug -a "var=hostvars[inventory_hostname].ansible_host" all

zk01 | SUCCESS => {
    "hostvars[inventory_hostname].ansible_host": "192.168.10.125"
}
NOZUONOHIGH
quelle
1

http://docs.ansible.com/ansible/latest/plugins/lookup/dig.html

so in Vorlage, zum Beispiel:

{{ lookup('dig', ansible_host) }}

Anmerkungen:

  • Da nicht nur der DNS-Name im Inventar verwendet werden kann, sollte eine Überprüfung, ob es sich nicht um eine IP handelt, bereits hinzugefügt werden
  • Offensichtlich würde diese Quittung nicht wie für indirekte Hostspezifikationen vorgesehen funktionieren (wie z. B. die Verwendung von Sprunghosts).

Dennoch dient es 99% (im übertragenen Sinne) der Anwendungsfälle.

poige
quelle
1
Und was ist, wenn DNS nicht in der Umgebung verwendet wird?
Techraf
(Oder ich fühle Ihren Schmerz. Andernfalls werden Sie solche naiven Fragen nicht stellen.) - Wenn DNS nicht im Inventar verwendet wird, verwenden Sie einfach ansible_host direkt, wie in meiner Antwort angegeben.
Poige
1
Abs was ist, wenn ansible_hostnicht die IP-Adresse des betreffenden Hosts ist?
Techraf
das ist nicht "und was". Es ist nur "was", weil Ihre zuvor gestellte Frage nicht gezählt wird. Vergessen Sie nicht.
Poige
1
Ich habe keine Ahnung, was Sie als "echte IP-Adresse" bezeichnen. Kennst du einige unwirkliche?
Poige
1

ansible_default_ipv4.addressIn einigen Fällen ist Plain möglicherweise nicht das, was Sie denken . Verwenden Sie:

ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0])
RafalS
quelle
0

Das folgende Snippet gibt die öffentliche IP-Adresse des Remote-Computers sowie die Standard-IP-Adresse (dh LAN) zurück.

Dadurch werden IPs in Anführungszeichen gedruckt, um Verwirrung bei der Verwendung von Konfigurationsdateien zu vermeiden.

>> main.yml

---
- hosts: localhost
  tasks:
    - name: ipify
      ipify_facts:
    - debug: var=hostvars[inventory_hostname]['ipify_public_ip']
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
    - name: template
      template:
        src: debug.j2
        dest: /tmp/debug.ansible

>> templates/debug.j2

public_ip={{ hostvars[inventory_hostname]['ipify_public_ip'] }}
public_ip_in_quotes="{{ hostvars[inventory_hostname]['ipify_public_ip'] }}"

default_ipv4={{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}
default_ipv4_in_quotes="{{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}"

Akhil Jalagam
quelle
2
Einige Kommentare von Ihnen würden diese Antwort verbessern
Marged
0

Verwenden Sie einfach eine ansible_ssh_hostVariable

playbook_example.yml

- hosts: host1
  tasks:
  - name: Show host's ip
    debug:
      msg: "{{ ansible_ssh_host }}"

hosts.yml

[hosts]
host1   ansible_host=1.2.3.4

Ergebnis

TASK [Show host's ip] *********************************************************************************************************************************************************************************************
ok: [host1] => {
     "msg": "1.2.3.4"
}
Andrey Bistrinin
quelle