Himanshu sharma
Himanshu sharma

Reputation: 7909

I want to access ansible inventory value one by one in ansible playbook?

I have very simple use case. I want to access my inventory variable into playbook one by one.

Folder structure:-

enter image description here

So i run ansible-playbook -vvv playbooks/deploy-sevice-sub.yaml -i inventory/inventorysub.

inventorysub is this.

[dev]
host=127.0.0.1 user=test pass=test
host=127.0.0.2 user=test pass=test

deploy-service-sub.yaml is

---
- name: Step to push sub
  hosts: dev
  roles:
    - deploy-service-package

role/deploy-service-package\task\main.yaml is

- name: Print the gateway for each host when defined
  ansible.builtin.debug:
    msg: "System {{ hostvars['dev'].host }} has gateway {{ hostvars['dev'].host }}"

I can run command on those server one by one, i want to access those value only, no ssh connect.

It throw error

fatal: [nso_host=127.0.0.1]: UNREACHABLE! => {

    "changed": false,

    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname nso_host=127.0.0.1: Name or service not known",

    "unreachable": true

}

fatal: [nso_host=127.0.0.1]: UNREACHABLE! => {

    "changed": false,

    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname nso_host=127.0.0.2: Name or service not known",

    "unreachable": true

}

I don't need it to connect, just access value from inventory. How can i access host one by one into my task file? Any idea?

Upvotes: 0

Views: 626

Answers (1)

larsks
larsks

Reputation: 311750

If you are accessing your hostvars using the hostvars variable, you don't need to target the remote hosts in the play: you can write instead a play that targets localhost.

We can use a loop to loop over a specific inventory group (or all for all hosts):

- hosts: localhost
  gather_facts: false
  tasks:
    - name: Print the gateway for each host when defined
      ansible.builtin.debug:
        msg: "System {{ item }} has gateway {{ hostvars[item].host }}"
      loop: "{{ groups.dev }}"

Given an inventory file like:

all:
  children:
    dev:
      hosts:
        node1:
          host: 127.0.0.1
          user: test
          pass: test
        node2:
          host: 127.0.0.2
          user: test
          pass: test

This produces as output:

PLAY [localhost] ***************************************************************

TASK [Print the gateway for each host when defined] ****************************
ok: [localhost] => (item=node1) => {
    "msg": "System node1 has gateway 127.0.0.1"
}
ok: [localhost] => (item=node2) => {
    "msg": "System node2 has gateway 127.0.0.2"
}

PLAY RECAP *********************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Alternately, you can a playbook that targets the hosts in your inventory, but sets gather_facts: false. If you're only running debug tasks, the play won't need to connect to remote hosts:

- hosts: dev
  gather_facts: false
  tasks:
    - name: Print the gateway for each host when defined
      ansible.builtin.debug:
        msg: "System {{ inventory_hostname }} has gateway {{ host }}"

Which produces:

PLAY [dev] *********************************************************************

TASK [Print the gateway for each host when defined] ****************************
ok: [node1] => {
    "msg": "System node1 has gateway 127.0.0.1"
}
ok: [node2] => {
    "msg": "System node2 has gateway 127.0.0.2"
}

PLAY RECAP *********************************************************************
node1                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Upvotes: 1

Related Questions