Ansible: obtenga la dirección IP del host de destino actual


100

¿Cómo se obtiene la dirección IP del host actual en un rol?

Sé que puede obtener la lista de grupos de los que el host es miembro y el nombre de host del host, pero no puedo encontrar una solución para obtener la dirección IP.

Puede obtener el nombre de host usando {{inventory_hostname}}y el grupo usando{{group_names}}

He probado cosas como {{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }} yip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

Respuestas:


124

Una lista de todas las direcciones se almacena en un hecho ansible_all_ipv4_addresses, una dirección predeterminada en ansible_default_ipv4.address.

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

Luego están las direcciones asignadas a cada interfaz de red ... En tales casos, puede mostrar todos los hechos y encontrar el que tiene el valor que desea utilizar.


¿Cómo se muestran todas las banderas?
SJC

1
¿Puede enumerar todas las banderas de una tarea?
SJC

2
@SJC Banderas? ¿Te refieres a hechos, verdad? Sí, ejecutar setup:módulo con register: allfactsy mostrar con- debug: var=allfacts
techraf

4
el valor de gather_factsdebe ser truepara que esto funcione. es verdadero de forma predeterminada, pero se puede convertir en falso si no se requiere la información sobre los hosts.
shshnk

1
@poige Podría ser incorrecto si hace una nueva pregunta, como lo hace.
techraf

69

Puede obtener la dirección IP de hostvars, dict ansible_default_ipv4y keyaddress

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

y dirección IPv6 respectivamente

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

Un ejemplo de libro de jugadas:

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

Esto puede fallar en algunos casos, vea esto: medium.com/opsops/…
RafalS

25

Puede usar en su template.j2 de {{ ansible_eth0.ipv4.address }}la misma manera que usa {{inventory_hostname}}.

ps: consulte la siguiente publicación de blog para obtener más información sobre CÓMO RECOPILAR INFORMACIÓN SOBRE HOSTS REMOTOS CON HECHOS ANSIBLES GATHERS .

'esperando que algún día ayude a alguien ッ


13
Tenga mucho cuidado. Hoy en día, la interfaz de red predeterminada no siempre es 'eth0'. A veces llamaba ens3o enp2s0y esas cosas. Simplemente tiene mejores apuestas si usa ansible_default_ipv4y si no funciona, vuelva a buscar algunos valores predeterminados cuerdos.
Gabor Garami

4
Esto probablemente solía funcionar en el pasado, pero con Ansible 2.7 esta variable no está definida.
Dirk

5

Si desea la IP pública externa y se encuentra en un entorno de nube como AWS o Azure, puede usar el módulo 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:

Esto colocará la IP pública en la variable ipify_public_ip.


Esto no siempre funciona. Para mí, la ipify_public_ipvariable está vacía
Davide

2
Para AWS, el nombre de host de inventario será la dirección IP.
Berend de Boer

Este complemento puede funcionar dentro de un cierto conjunto de circunstancias, si accede a Internet desde detrás de un NAT, no funcionará. Básicamente, esto funciona cuando los servidores son accesibles a Internet y pueden acceder al sitio web ipify.org para resolver su IP externa al acceder al sitio.
slm

1
@BerenddeBoer Incorrecto. inventory_hostnamees lo que se establece en el inventario. Podría ser un nombre de host como se establece en .ssh/config.
Teresa e Junior

@slm como dije, si está buscando la IP pública externa. Si está detrás de una NAT, entonces no tendrá una IP externa de acceso público, por lo que no usaría este método.
Simon Woodside

4

Otra forma de encontrar IP pública sería usar el urimódulo:

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

Tu IP estará en ip_response.content


Otra URL de servicio que devuelve lo mismo es:https://ipecho.net/plain
Paul Parker

@PaulParker ipecho.net/plain parece KO o pide api token ... ifconfig.me mejor y servicio estable desde hace años: +1
bastien

Nunca se le pidió un token de API. No puedo hablar de la consistencia del servicio, no lo he monitoreado, pero nunca me ha fallado.
Paul Parker

2

Comando de depuración simple:

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

salida:

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

obtener la dirección IP del 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"
}

1

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

así que en la plantilla, por ejemplo:

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

Notas:

  • Dado que no solo se puede usar el nombre DNS en el inventario, es mejor agregar una verificación si no es IP
  • Obviamente, este recibo no funcionaría según lo previsto para las especificaciones de host indirecto (como usar hosts de salto, por ejemplo)

Pero aún sirve al 99% (en sentido figurado) de los casos de uso.


1
¿Y si no se utiliza DNS en el medio ambiente?
techraf

(O, siento su dolor. De lo contrario, no hará preguntas ingenuas como esa). - Si el DNS no se usa en el inventario uno, simplemente use ansible_host directamente como se indica en mi respuesta.
poige

1
Abs, ¿y si ansible_hostno es la dirección IP del host en cuestión?
techraf

esto no es "y qué". Es solo "qué" porque su pregunta anterior no se cuenta, no lo olvide.
poige

1
No tengo ni idea de lo que está llamando como "dirección IP real". ¿Conoces algunos irreales?
poige

1

ansible_default_ipv4.addressPuede que simple no sea lo que piensas en algunos casos , usa:

ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0])

0

El siguiente fragmento devolverá la IP pública de la máquina remota y también la IP predeterminada (es decir: LAN)

Esto también imprimirá las direcciones IP entre comillas para evitar confusiones al usar archivos de configuración.

>> 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
Algunos comentarios
tuyos

0

Solo usa 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

Resultado

TASK [Show host's ip] *********************************************************************************************************************************************************************************************
ok: [host1] => {
     "msg": "1.2.3.4"
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.