Tomáš Fejfar
Tomáš Fejfar

Reputation: 11217

How to get IP address of hostname inside jinja template

Our saltstack is based on hostnames (webN., dbN., etc.). But for various things I need IPs of those servers. For now I had them stored in pillars, but the number of places I need to sync grows.

I tried to use publish + network.ip_addrs, but that kinda sucks, because it needs to do the whole salt-roundtrip just to resolve a hostname. Also it's dependent on the minions responding. Therefore I'm looking for a way to resolve hostname to IP in templates.

I assume that I could write a module for it somehow, but my python skills are very limited.

Upvotes: 12

Views: 23842

Answers (7)

rilCy
rilCy

Reputation: 413

If you need to get IPs that are not available in grains, do not want to setup custom grains and need those IPs to be dynamically resolved in your pillars ( typically to setup the firewall, network interfaces, BGP to the host, etc. ) you can proceed as follow:

Let's say you have:

  • idrac-hostname.domain
  • management-hostname.domain
  • hostname.domain

Then you can just resolv them using the dig modules from SaltStack

{% set fqdn = salt['grains.get']('fqdn') %}
{% set idrac = 'idrac-' ~ fqdn %}

{% set idrac_ip = salt['dig.A'](idrac)[0] %}
{% set main_ip = salt['dig.A'](fqdn)[0] %}

Hope it helps

Ref: https://docs.saltproject.io/en/latest/ref/modules/all/salt.modules.dig.html

Upvotes: 0

David Meiser
David Meiser

Reputation: 71

This is a very old post, but it is highly ranked in Google for getting the ipv4 address. As of salt 2015.5.8, the best way to get the primary ipv4 address is {{ grains['ipv4'][0] }}.

Upvotes: 4

easai
easai

Reputation: 81

Just a reminder, you always can pass it from Flask app.

import os

host = os.uname()[1]

return render_template("template.html", host=host)

Upvotes: 0

Bhav
Bhav

Reputation: 21

Reading through the ansible documentation, I found a much simpler solution. Here are my results.

enter the following into the template:

lookup hostname: {{ lookup('dig', 'google.ca.') }}

My jinja2 template:

# mytemplate.j2
## lookup directly
lookup hostname: {{ lookup('dig', 'google.ca.') }}

## in a variable
{% set fqdn = 'google.ca' %}
lookup hostname: {{ lookup('dig', fqdn) }}

Result:

# mytemplate.j2
## lookup directly
lookup hostname: 172.217.2.163

## in a variable
lookup hostname: 172.217.2.163

Upvotes: 2

José Ibañez
José Ibañez

Reputation: 712

I've see this: http://cnygaard.blogspot.com.es/2012/11/how-to-template-eth0-address-with.html

This is the easy way that I've found.

#init.sls:

...
...

/etc/swift/proxy-server.conf:              
   file:
     - managed                              
     - source: salt://swift/proxy-server.conf
     - template: jinja
     - context:
         proxy_ip: {{ salt['network.interfaces']()['eth0']['inet'][0]['address'] }}

And then:

#In proxy-server.conf

...

[filter:cache]
use = egg:swift#memcache
memcache_servers = {{ proxy_ip }}:11211

Upvotes: 5

Dan Garthwaite
Dan Garthwaite

Reputation: 3526

Currently - to aggregate a list of all ip addresses requires either salt-mine or interrogating all minions. I prefer salt-mine.

There is an accepted issue to extend the new roster system to maintain addresses of all minions, not just ssh based hosts. https://github.com/saltstack/salt/issues/7759

Upvotes: 1

kubus
kubus

Reputation: 783

You could use a custom grain. Create file _grains/fqdn_ip.py in the state tree directory:

import socket

def fqdn_ip():
    return {
        'fqdn_ip': socket.gethostbyname(socket.getfqdn())
    }

In template:

{{ grains.fqdn_ip }}

Another way is use dnsutil module (requires dig command on minion):

{{ salt['dnsutil.A']('host.name.tld')[0] }}

Upvotes: 12

Related Questions