Ansible: ottiene l'indirizzo IP dell'host di destinazione corrente


102

Come si ottiene l'indirizzo IP dell'host corrente in un ruolo?

So che puoi ottenere l'elenco dei gruppi di cui l'host è membro e il nome host dell'host, ma non riesco a trovare una soluzione per ottenere l'indirizzo IP.

È possibile ottenere il nome host utilizzando {{inventory_hostname}}e il gruppo utilizzando{{group_names}}

Ho provato cose come {{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }} eip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

Risposte:


127

Un elenco di tutti gli indirizzi è memorizzato in un fatto ansible_all_ipv4_addresses, un indirizzo predefinito in ansible_default_ipv4.address.

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

Poi ci sono indirizzi assegnati ad ogni interfaccia di rete ... In questi casi puoi visualizzare tutti i fatti e trovare quello che ha il valore che vuoi usare.


Come vengono visualizzate tutte le bandiere?
SJC

1
Puoi elencare tutti i flag all'interno di un'attività?
SJC

2
@SJC Flags? Intendi fatti, giusto? Sì, esegui il setup:modulo con register: allfactse visualizza con- debug: var=allfacts
techraf

4
il valore di gather_factsdeve essere trueperché funzioni. è vero per impostazione predefinita, ma è possibile trasformarlo in falso se le informazioni sugli host non sono richieste.
shshnk

1
@poige Potrebbe non essere corretto se fai una nuova domanda, come fai.
techraf

70

Puoi ottenere l'indirizzo IP da hostvars, dict ansible_default_ipv4e keyaddress

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

e l'indirizzo IPv6 rispettivamente

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

Un esempio di playbook:

---
- hosts: localhost
  tasks:
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv6']['address']

In alcuni casi potrebbe non funzionare, vedi questo: medium.com/opsops/…
RafalS

25

Puoi usarlo nel tuo template.j2 {{ ansible_eth0.ipv4.address }}nello stesso modo in cui usi {{inventory_hostname}}.

ps: Si prega di fare riferimento al seguente post sul blog per avere maggiori informazioni su COME RACCOGLIERE INFORMAZIONI SUGLI HOST REMOTI CON ANSIBLE GATHERS FACTS .

'sperando che un giorno possa aiutare qualcuno ッ


13
Stai molto attento. Al giorno d'oggi l'interfaccia di rete predefinita non è sempre "eth0". A volte chiamava ens3o enp2s0e cose del genere. Hai solo scommesse migliori se usi ansible_default_ipv4e se non funziona, torna indietro alla ricerca di alcuni valori predefiniti sani.
Gabor Garami

4
Questo probabilmente funzionava in passato, ma con Ansible 2.7 questa variabile non è definita.
Dirk

5

Se desideri l' IP pubblico esterno e ti trovi in ​​un ambiente cloud come AWS o Azure, puoi utilizzare il modulo 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:

Questo inserirà l'IP pubblico nella variabile ipify_public_ip.


Questo non sempre funziona. Per me la ipify_public_ipvariabile è vuota
Davide

2
Per AWS, inventario_hostname sarà l'indirizzo IP.
Berend de Boer

Questo plugin può funzionare in un certo insieme di circostanze, se accedi a Internet da dietro un NAT, non funzionerà. Fondamentalmente questo funziona quando i server sono accessibili a Internet e possono colpire il sito Web ipify.org per risolvere il loro IP esterno quando si accede al sito.
slm

1
@BerenddeBoer Sbagliato. inventory_hostnameè tutto ciò che è impostato nell'inventario. Potrebbe essere un nome host impostato in .ssh/config.
Teresa e Junior

@slm come ho detto, se stai cercando l'IP pubblico esterno. Se sei dietro un NAT, non avrai un IP esterno accessibile pubblicamente, quindi non useresti questo metodo.
Simon Woodside

4

Un altro modo per trovare un IP pubblico sarebbe usare il urimodulo:

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

Il tuo IP sarà in ip_response.content


Un altro URL del servizio che restituisce lo stesso è:https://ipecho.net/plain
Paul Parker

@PaulParker ipecho.net/plain sembra KO o chiedi api token ... ifconfig.me servizio migliore e stabile da anni: +1
bastien

Non è mai stato chiesto un token API. Non posso parlare della coerenza del servizio, non l'ho monitorato, ma non mi ha mai deluso.
Paul Parker,

3

Semplice comando di debug:

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

produzione:

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

ottenere l'indirizzo IP dell'host:

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

2

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

quindi nel modello, ad esempio:

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

Appunti:

  • Poiché non solo il nome DNS potrebbe essere utilizzato nell'inventario, è meglio aggiungere un controllo se non è IP
  • Ovviamente abbastanza questa ricevuta non funzionerebbe come previsto per le specifiche host indirette (come l'utilizzo di host jump, ad esempio)

Ma serve ancora il 99% (in senso figurato) dei casi d'uso.


1
E se il DNS non viene utilizzato nell'ambiente?
techraf

(Oppure, sento il tuo dolore. Altrimenti non farai domande ingenue del genere.) - Se il DNS non viene utilizzato nell'inventario, usa ansible_host direttamente come indicato nella mia risposta.
poige

1
Abs cosa succede se ansible_hostnon è l'indirizzo IP dell'host in questione?
techraf

questo non è "e cosa". È solo "cosa" perché la tua domanda precedente non viene conteggiata, non dimenticare.
poige

1
Non ho idea di cosa tu chiami "vero indirizzo IP". Ne conosci alcuni irreali?
poige

1

Plain ansible_default_ipv4.addresspotrebbe non essere quello che pensi in alcuni casi , usa:

ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0])

0

Il seguente frammento restituirà l'ip pubblico della macchina remota e anche l'ip predefinito (ad esempio: LAN)

Questo stamperà gli ip tra virgolette anche per evitare confusione nell'uso dei file di configurazione.

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


2
Alcuni tuoi commenti migliorerebbero questa risposta
Marged

0

Usa solo la ansible_ssh_hostvariabile

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

Risultato

TASK [Show host's ip] *********************************************************************************************************************************************************************************************
ok: [host1] => {
     "msg": "1.2.3.4"
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.