Ansible: obtenir l'adresse IP actuelle de l'hôte cible

100

Comment obtenir l'adresse IP de l'hôte actuel dans un rôle?

Je sais que vous pouvez obtenir la liste des groupes dont l'hôte est membre et le nom d'hôte de l'hôte, mais je ne parviens pas à trouver une solution pour obtenir l'adresse IP.

Vous pouvez obtenir le nom d'hôte en utilisant {{inventory_hostname}}et le groupe en utilisant{{group_names}}

J'ai essayé des choses comme {{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }} etip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

SJC
la source

Réponses:

124

Une liste de toutes les adresses est stockée dans un fait ansible_all_ipv4_addresses, une adresse par défaut dans ansible_default_ipv4.address.

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

Ensuite, il y a des adresses attribuées à chaque interface réseau ... Dans de tels cas, vous pouvez afficher tous les faits et trouver celui qui a la valeur que vous souhaitez utiliser.

techraf
la source
Comment affichez-vous tous les drapeaux?
SJC
1
Pouvez-vous lister tous les indicateurs d'une tâche?
SJC
2
Drapeaux @SJC? Vous voulez dire des faits, non? Oui, exécuter le setup:module avec register: allfactset afficher avec- debug: var=allfacts
techraf
4
la valeur de gather_factsdoit être truepour que cela fonctionne. c'est vrai par défaut mais on peut le transformer en faux si les informations sur les hôtes ne sont pas requises.
shshnk le
1
@poige Cela peut être incorrect si vous posez une nouvelle question, comme vous le faites.
techraf
69

Vous pouvez obtenir l'adresse IP de hostvars, dict ansible_default_ipv4et cléaddress

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

et adresse IPv6 respectivement

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

Un exemple de playbook:

---
- hosts: localhost
  tasks:
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv6']['address']
Pasi H
la source
Cela peut échouer dans certains cas, voir ceci: medium.com/opsops/…
RafalS
25

Vous pouvez utiliser dans votre template.j2 de {{ ansible_eth0.ipv4.address }}la même manière que vous utilisez {{inventory_hostname}}.

ps: Veuillez vous référer au blog suivant pour avoir plus d'informations sur COMMENT COLLECTER DES INFORMATIONS SUR LES HÔTES À DISTANCE AVEC DES FAITS ANSIBLE GATHERS .

'en espérant que ça aidera quelqu'un un jour ッ

Orsius
la source
13
Soyez très prudent. De nos jours, l'interface réseau par défaut n'est pas toujours «eth0». Il a parfois appelé ens3ou enp2s0et de telles choses. Vous avez juste de meilleurs paris si vous utilisez ansible_default_ipv4et si cela ne fonctionne pas, puis revenez à la recherche de valeurs par défaut saines.
Gabor Garami
4
Cela fonctionnait probablement dans le passé, mais avec Ansible 2.7, cette variable n'est pas définie.
Dirk
5

Si vous voulez l' adresse IP publique externe et que vous êtes dans un environnement cloud comme AWS ou Azure, vous pouvez utiliser le module 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:

Cela placera l'adresse IP publique dans la variable ipify_public_ip.

Simon Woodside
la source
Cela ne fonctionne pas toujours. For me ipify_public_ipvariable is empty
Davide
2
Pour AWS, nom_hôte_inventaire sera l'adresse IP.
Berend de Boer
Ce plugin peut fonctionner dans un certain ensemble de circonstances, si vous accédez à Internet derrière un NAT, cela ne fonctionnera pas. Fondamentalement, cela fonctionne lorsque les serveurs sont accessibles sur Internet et peuvent accéder au site Web ipify.org pour résoudre leur adresse IP externe lors de l'accès au site.
slm
1
@BerenddeBoer Faux. inventory_hostnameest ce qui est défini dans l'inventaire. Il peut s'agir d'un nom d'hôte tel que défini dans .ssh/config.
Teresa e Junior
@slm comme je l'ai dit, si vous recherchez l'adresse IP publique externe. Si vous êtes derrière un NAT, vous n'aurez pas d'adresse IP externe accessible au public, vous n'utiliserez donc pas cette méthode.
Simon Woodside
4

Une autre façon de trouver une adresse IP publique serait d'utiliser le urimodule:

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

Votre adresse IP sera en ip_response.content

chava
la source
Une autre URL de service qui renvoie la même chose est:https://ipecho.net/plain
Paul Parker
@PaulParker ipecho.net/plain semble KO ou demander un jeton api ... ifconfig.me service meilleur et stable depuis des années: +1
bastien
Jamais été demandé un jeton API. Je ne peux pas parler de la cohérence du service, je ne l'ai pas surveillé, mais cela ne m'a jamais déçu.
Paul Parker
2

Commande de débogage simple:

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

production:

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

obtenir l'adresse IP de l'hôte:

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
la source
1

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

donc dans le modèle, par exemple:

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

Remarques:

  • Étant donné que non seulement le nom DNS peut être utilisé dans l'inventaire, il vaut mieux vérifier si ce n'est pas déjà IP
  • De toute évidence, ce reçu ne fonctionnerait pas comme prévu pour les spécifications d'hôte indirectes (comme l'utilisation d'hôtes de saut, par exemple)

Mais il sert toujours 99% (au sens figuré) des cas d'utilisation.

poige
la source
1
Et si le DNS n'est pas utilisé dans l'environnement?
techraf
(Ou, je ressens votre douleur. Sinon, vous ne poserez pas de questions naïves comme ça.) - Si le DNS n'est pas utilisé dans l'inventaire, il suffit d'utiliser ansible_host directement comme indiqué dans ma réponse.
poige
1
Abs et si ce ansible_hostn'est pas l'adresse IP de l'hôte en question?
techraf
ce n'est pas «et quoi». C'est juste "quoi" parce que votre question précédemment posée n'est pas comptée, n'oubliez pas.
poige
1
Je n'ai aucune idée de ce que vous appelez "vraie adresse IP". Connaissez-vous des irréels?
poige
1

Plain ansible_default_ipv4.addresspeut ne pas être ce que vous pensez dans certains cas , utilisez:

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

L'extrait de code suivant renverra l'IP publique de la machine distante ainsi que l'IP par défaut (c'est-à-dire: LAN)

Cela imprimera également les adresses IP entre guillemets pour éviter toute confusion lors de l'utilisation des fichiers de configuration.

>> 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
la source
2
Quelques commentaires de votre part amélioreraient cette réponse
Marged
0

Utilisez simplement la 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

Résultat

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