Search code examples
ansibleansible-inventory

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?


Solution

  • 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