Ansible: obtenha o endereço IP do host de destino atual

100

Como você obtém o endereço IP do host atual em uma função?

Sei que você pode obter a lista de grupos dos quais o host é membro e o nome do host do host, mas não consigo encontrar uma solução para obter o endereço IP.

Você pode obter o nome do host usando {{inventory_hostname}}e o grupo usando{{group_names}}

Eu tentei coisas como {{ hostvars[{{ inventory_hostname }}]['ansible_ssh_host'] }} eip="{{ hostvars.{{ inventory_hostname }}.ansible_ssh_host }}"

SJC
fonte

Respostas:

124

Uma lista de todos os endereços é armazenada em um fato ansible_all_ipv4_addresses, um endereço padrão emansible_default_ipv4.address .

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

Depois, há endereços atribuídos a cada interface de rede ... Nesses casos, você pode exibir todos os fatos e encontrar aquele que tem o valor que deseja usar.

techraf
fonte
Como você exibe todas as bandeiras?
SJC de
1
Você pode listar todos os sinalizadores de uma tarefa?
SJC de
2
@SJC Flags? Você quer dizer fatos, certo? Sim, execute o setup:módulo com register: allfactse exiba com- debug: var=allfacts
techraf
4
o valor de gather_factsdeve ser truepara que isso funcione. é verdadeiro por padrão, mas pode ser alterado para falso se as informações sobre os hosts não forem necessárias.
shshnk
1
@poige Pode ser incorreto se você fizer uma nova pergunta, como você faz.
techraf de
69

Você pode obter o endereço IP de hostvars, dict ansible_default_ipv4e keyaddress

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

e endereço IPv6 respectivamente

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

Um exemplo de manual:

---
- hosts: localhost
  tasks:
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv4']['address']
    - debug: var=hostvars[inventory_hostname]['ansible_default_ipv6']['address']
Pasi H
fonte
Isso pode falhar em alguns casos, consulte: medium.com/opsops/…
RafalS
25

Você pode usar em seu template.j2 {{ ansible_eth0.ipv4.address }}da mesma maneira que usa{{inventory_hostname}} .

ps: Consulte a seguinte postagem do blog para obter mais informações sobre COMO COLETAR INFORMAÇÕES SOBRE HOSTS REMOTOS COM FATOS DE COLETA ANSÍVEIS .

'esperando que ajude alguém um dia ッ

Orsius
fonte
13
Seja extremamente cuidadoso. Hoje em dia, a interface de rede padrão nem sempre é 'eth0'. Às vezes é chamado de ens3ou enp2s0e essas coisas. Você só tem apostas melhores se usar ansible_default_ipv4e se não estiver funcionando, então volte procurando por alguns padrões sensatos.
Gabor Garami
4
Isso provavelmente costumava funcionar no passado, mas com o Ansible 2.7 essa variável é indefinida.
Dirk
5

Se você deseja o IP público externo e está em um ambiente de nuvem como AWS ou Azure, pode usar o 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:

Isso colocará o IP público na variável ipify_public_ip.

Simon Woodside
fonte
Isso nem sempre funciona. Para mim, a ipify_public_ipvariável está vazia
Davide
2
Para AWS, inventory_hostname será o endereço IP.
Berend de Boer
Este plugin pode funcionar em um determinado conjunto de circunstâncias, se você estiver acessando a internet por trás de um NAT, ele não funcionará. Basicamente, isso funciona quando os servidores estão acessíveis à internet e podem acessar o site ipify.org para resolver seu IP externo ao acessar o site.
slm
1
@BerenddeBoer Wrong. inventory_hostnameé tudo o que está definido no inventário. Pode ser um nome de host conforme definido em .ssh/config.
Teresa e Junior de
@slm como eu disse, se você está procurando o IP público externo. Se você estiver atrás de um NAT, não terá um IP externo acessível publicamente, portanto, não usaria esse método.
Simon Woodside
4

Outra maneira de encontrar IP público seria usar o urimódulo:

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

Seu IP estará em ip_response.content

chava
fonte
Outro url de serviço que retorna o mesmo é:https://ipecho.net/plain
Paul Parker de
@PaulParker ipecho.net/plain parece KO ou pede token de API ... ifconfig.me serviço melhor e estável desde anos: +1
bastien
Nunca foi solicitado um token de API. Não posso falar sobre a consistência do serviço, não acompanhei, mas nunca falhou.
Paul Parker
2

Comando de depuração simples:

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

resultado:

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

obter o endereço IP do 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"
}
NOZUONOHIGH
fonte
1

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

então no modelo, por exemplo:

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

Notas:

  • Visto que não apenas o nome DNS pode ser usado no inventário, verifique se não é IP já é melhor ser adicionado
  • Obviamente, este recibo não funcionaria como pretendido para especificações de host indiretas (como usar hosts de salto, por exemplo)

Mas ainda assim atende a 99% (falando figurativamente) dos casos de uso.

poige
fonte
1
E se o DNS não for usado no ambiente?
techraf de
(Ou, eu sinto sua dor. Do contrário, você não fará perguntas ingênuas como essa.) - Se o DNS não for usado no inventário, use ansible_host diretamente, conforme indicado em minha resposta.
Poige
1
Abs, e se ansible_hostnão for o endereço IP do host em questão?
techraf
isso não é "e o quê". É apenas "o quê" porque sua pergunta feita anteriormente não é contada, não se esqueça.
poige
1
Não tenho ideia do que você está chamando de "endereço IP real". Você conhece alguns irreais?
poige
1

Simples ansible_default_ipv4.addresspode não ser o que você pensa em alguns casos , use:

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

O seguinte snippet retornará o ip público da máquina remota e também o ip padrão (ou seja: LAN)

Isso imprimirá ips entre aspas também para evitar confusão no uso de arquivos de configuração.

>> 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
fonte
2
Alguns comentários seus melhorariam esta resposta
Marcado em
0

Basta usar ansible_ssh_hostvariável

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"
}
Andrey Bistrinin
fonte