n00b
n00b

Reputation: 57

Ansible Get Host Name and IP for Inventory Host groups

I am trying to get host name and IP address of hosts and save them to a file.

I have this solution working;

- name: Create File with hosts and IP address.
  when: inventory_hostname in groups['local']
  lineinfile:
    dest: "{{store_files_path}}/{{ansible_date_time.date}}/{{ansible_date_time.time}}/hosts.txt"
    create: yes
    line: "{{hostvars[inventory_hostname].ansible_hostname}}:{{hostvars[inventory_hostname].ansible_default_ipv4.address}}"

But the issue is in my hosts file, I have two groups, local and Servers. I want to get the Servers only and not the local group which is the localhost only.

I have tried the below line but it doesn't work, it gives me an error.

line: "{{ hostvars[ groups['Servers'][0] ].ansible_hostname }} :{{ hostvars[ groups['Servers'][0] ].ansible_default_ipv4.address }}"

I have searched around and that's what I found, how should I do this?

Upvotes: 3

Views: 30720

Answers (2)

Marc Salvetti
Marc Salvetti

Reputation: 362

I would use a jinja template for this :

# hosts_file.j2
{% for server in groups['Servers'] %}
{{hostvars[server]['ansible_facts']['hostname']}}:{{hostvars[server]['ansible_facts']['default_ipv4']['address']}}
{% endfor %}
- hosts: localhost
  tasks:
    - name: create hosts file from template
      template: 
        src: hosts_file.j2
        dest: {{store_files_path}}/{{ansible_date_time.date}}/{{ansible_date_time.time}}/hosts.txt

Upvotes: 3

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39355

You are making this extremely complicated for yourself.

  1. You don't have to go via the hostvars in order to achieve what you want, the special variables are mostly giving you information on the host Ansible is currently acting on. This is the same for the facts Ansible gathered for the hosts.
  2. For the matter at hand, you can use another special variable group_names that will allow you to get the groups the host you are currently acting on is, in the form of a list. So getting the hosts that are part of a group is as simple as doing when: "'group_that_interest_you' in group_names"

So given the inventory:

all:
  vars:
    ansible_python_interpreter: /usr/bin/python3

  children:
    local:
      hosts:
        localhost:

    Servers:
      hosts:
        foo.example.org:
          ansible_host: 172.17.0.2

And the playbook:

- hosts: all
  gather_facts: yes
      
  tasks:
    - debug:
        msg: "{{ ansible_hostname }}:{{ ansible_default_ipv4.address }}"
      when:  "'Servers' in group_names"

This yields the recap:

PLAY [all] **********************************************************************************************************

TASK [Gathering Facts] **********************************************************************************************
ok: [localhost]
ok: [foo.example.org]

TASK [debug] ********************************************************************************************************
skipping: [localhost]
ok: [foo.example.org] => {
    "msg": "8088bc73d8cf:172.17.0.2"
}

PLAY RECAP **********************************************************************************************************
foo.example.org            : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

Now if you adapt that in your own playbook you should be good to go:

- name: Create File with hosts and IP address.
  lineinfile:
    dest: "{{ store_files_path }}/{{ ansible_date_time.date }}/{{ ansible_date_time.time }}/hosts.txt"
    create: yes
    line: "{{ ansible_hostname }}:{{ ansible_default_ipv4.address }}"
  when:  "'Servers' in group_names"
  delegate_to: localhost

Upvotes: 5

Related Questions