Ansible: pobierz aktualny adres IP hosta docelowego

101

Jak uzyskać adres IP obecnego hosta w roli?

Wiem, że możesz uzyskać listę grup, których członkiem jest host, oraz nazwę hosta, ale nie mogę znaleźć rozwiązania, aby uzyskać adres IP.

Nazwę hosta można uzyskać za pomocą, {{inventory_hostname}}a grupę przy użyciu{{group_names}}

Próbowałem takich rzeczy jak {{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }} iip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

SJC
źródło

Odpowiedzi:

126

W rzeczywistości lista wszystkich adresów jest przechowywana ansible_all_ipv4_addresses, domyślny adres w formacie ansible_default_ipv4.address.

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

Następnie są przypisane adresy do każdego interfejsu sieciowego ... W takich przypadkach możesz wyświetlić wszystkie fakty i znaleźć ten, który ma wartość, której chcesz użyć.

techraf
źródło
Jak wyświetlić wszystkie flagi?
SJC
1
Czy potrafisz wyświetlić listę wszystkich flag z poziomu zadania?
SJC
2
@SJC Flags? Masz na myśli fakty, prawda? Tak, uruchom setup:moduł register: allfacts- debug: var=allfacts
zi
4
wartość gather_factsmusi być, trueaby to zadziałało. jest to domyślnie prawda, ale można zmienić ją na fałsz, jeśli informacje o hostach nie są wymagane.
shshnk
1
@poige Może to być niepoprawne, jeśli zadasz nowe pytanie, tak jak ty.
techraf
70

Możesz uzyskać adres IP z hostvars, dict ansible_default_ipv4i keyaddress

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

i adres IPv6 odpowiednio

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

Przykładowy poradnik:

---
- hosts: localhost
  tasks:
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv6']['address']
Pasi H
źródło
W niektórych przypadkach może się to nie udać, zobacz to: medium.com/opsops/ ...
RafalS,
25

Możesz użyć w swoim template.j2 w {{ ansible_eth0.ipv4.address }}taki sam sposób jak używasz {{inventory_hostname}}.

ps: Zapoznaj się z następującym postem na blogu, aby uzyskać więcej informacji na temat JAK ZBIERAĆ INFORMACJE O ZDALNYCH HOSTACH Z PRAWIDŁOWYMI ZBIORAMI FAKTÓW .

mam nadzieję, że kiedyś komuś pomoże ッ

Orsius
źródło
13
Bądź bardzo ostrożny. Obecnie domyślnym interfejsem sieciowym nie zawsze jest „eth0”. Czasami nazywało się ens3lub enp2s0i takie rzeczy. Masz po prostu lepsze zakłady, jeśli używasz, ansible_default_ipv4a jeśli to nie działa, przełącz się z powrotem, szukając rozsądnych ustawień domyślnych.
Gabor Garami
4
Prawdopodobnie działało to w przeszłości, ale w Ansible 2.7 ta zmienna jest niezdefiniowana.
Dirk
5

Jeśli chcesz mieć zewnętrzny publiczny adres IP i jesteś w środowisku chmurowym, takim jak AWS lub Azure, możesz użyć modułu ipify_facts :

# 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:

Spowoduje to umieszczenie publicznego adresu IP w zmiennej ipify_public_ip.

Simon Woodside
źródło
To nie zawsze działa. Dla mnie ipify_public_ipzmienna jest pusta
Davide
2
W przypadku AWS nazwa_hosta_ inwentaryzacji będzie adresem IP.
Berend de Boer
Ta wtyczka może działać w określonych okolicznościach, jeśli uzyskujesz dostęp do Internetu zza NAT, to nie zadziała. Zasadniczo działa to, gdy serwery są dostępne w Internecie i mogą trafić na witrynę ipify.org, aby rozwiązać ich zewnętrzny adres IP podczas uzyskiwania dostępu do witryny.
slm
1
@BerenddeBoer Wrong. inventory_hostnamejest tym, co jest ustawione w ekwipunku. Może to być nazwa hosta ustawiona w .ssh/config.
Teresa e Junior
@slm, jak powiedziałem, jeśli szukasz zewnętrznego publicznego adresu IP. Jeśli jesteś za NATem, nie będziesz mieć zewnętrznego publicznie dostępnego adresu IP, więc nie będziesz używać tej metody.
Simon Woodside
4

Innym sposobem na znalezienie publicznego adresu IP byłoby użycie urimodułu:

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

Twoje IP będzie w ip_response.content

chava
źródło
Inny adres URL usługi, który zwraca to samo, to:https://ipecho.net/plain
Paul Parker
@PaulParker ipecho.net/plain wydaje się KO lub zapytaj token API ... ifconfig.me lepsza i stabilniejsza usługa od lat: +1
bastien
Nigdy nie zostałem poproszony o token API. Nie mogę mówić o spójności usługi, nie monitorowałem jej, ale nigdy mnie to nie zawiodło.
Paul Parker
3

Proste polecenie debugowania:

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

wynik:

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

pobierz adres IP hosta:

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
źródło
2

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

więc w szablonie, na przykład:

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

Uwagi:

  • Ponieważ nie tylko nazwa DNS może być używana w inwentaryzacji, sprawdź, czy nie jest to już adres IP, lepiej dodać
  • Oczywiście to potwierdzenie nie działałoby zgodnie z przeznaczeniem dla pośrednich specyfikacji hosta (jak używanie hostów przeskoku, na przykład)

Ale nadal obsługuje 99% (mówiąc w przenośni) przypadków użycia.

poige
źródło
1
A co jeśli DNS nie jest używany w środowisku?
techraf
(Albo czuję twój ból. W przeciwnym razie nie będziesz zadawał takich naiwnych pytań.) - Jeśli DNS nie jest używany w ekwipunku, po prostu użyj ansible_host bezpośrednio, jak wskazałem w mojej odpowiedzi.
poige
1
Abs, a co, jeśli ansible_hostnie jest to adres IP danego hosta?
techraf
to nie jest „i co”. Po prostu „co”, ponieważ Twoje wcześniej zadane pytanie nie jest liczone, nie zapomnij.
poige
1
Nie mam pojęcia, co nazywasz „prawdziwym adresem IP”. Czy znasz jakieś nierealne?
poige
1

Równina ansible_default_ipv4.address może nie być tym, co myślisz w niektórych przypadkach , użyj:

ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0])
RafalS
źródło
0

Poniższy fragment kodu zwróci publiczny adres IP zdalnego komputera, a także domyślny adres IP (tj .: LAN)

Spowoduje to również wyświetlenie adresów IP w cudzysłowach, aby uniknąć nieporozumień w używaniu plików konfiguracyjnych.

>> 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
źródło
2
Niektóre
Twoje
0

Po prostu użyj ansible_ssh_hostzmiennej

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

Wynik

TASK [Show host's ip] *********************************************************************************************************************************************************************************************
ok: [host1] => {
     "msg": "1.2.3.4"
}
Andrey Bistrinin
źródło