Serge Hartmann
Serge Hartmann

Reputation: 148

Ansible - items list from a variable list defined from inventory hostname

I have a variable named "bonding" in my host_vars - this is a list of network interfaces to be aggregated into bond0 interface. These values are defined in the inventory, and they are correctly listed in my variables for each host.

production/
├── group_vars
│   └── ipbatch.yaml
├── hosts.yaml
└── host_vars
    ├── ipbatch1.yaml
    ├── ipbatch2.yaml
    └── ipbatch3.yaml

content for production/host_vars/ipbatch3.yaml :

---
bonding:
  - eno3
  - eno4

checking this variable is correctly set :

tasks:
  - name: debug test - hostvars
    debug:
      var: hostvars[inventory_hostname]

output extract - looks correct :

        "ansible_virtualization_type": "kvm",
        "bonding": [
            "eno3",
            "eno4"
        ],
        "dns": true,
        "ftp": true,

Now, I want to use this variable in a role, this way :

  tasks:
    - set_fact:
        interface_bond: "{{ ansible_interfaces | select('match','^bond[0-9]') | sort | list | first }}"
  roles:
    - role: network
      network_ifaces:
      - device: "{{ item }}"
        bondmaster: "{{ interface_bond }}"
      with_items: "{{ hostvars[inventory_hostname][bonding] | list }}"

Here is the problem : ansible says my item list is empty. I'm trying to debug my variable request, this way :

    - debug:
        var: "{{ hostvars[inventory_hostname][bonding] | list }}"

The output is an error message. However, the correct values are displayed in the error message :

fatal: [ipbatch2]: FAILED! => {"msg": "ansible.vars.hostvars.HostVarsVars object has no element ['eno1']"}
fatal: [ipbatch1]: FAILED! => {"msg": "ansible.vars.hostvars.HostVarsVars object has no element ['eth0', 'eth1']"}
fatal: [ipbatch3]: FAILED! => {"msg": "ansible.vars.hostvars.HostVarsVars object has no element ['eno3', 'eno4']"}

What I have tried :

var: "{{ hostvars[inventory_hostname][bonding] | list }}"
var: "{{ bonding }}"
var: "{{ bonding | list }}"
var: "{{ map('extract','hostvars[inventory_hostname]','bonding')| list }}"
var:  "{{ hostvars[inventory_hostname] | map(attribute='bonding') | list }}"
var: "{{ hostvars[inventory_hostname].bonding | list }}"

But the nearest output, even if in error, is the first line.

Expected result : the with_items statement should return a list of ethernet interfaces, as described in host_vars inventory files

Upvotes: 2

Views: 3095

Answers (1)

Zeitounator
Zeitounator

Reputation: 44645

bonding is the name (as a string) of your key in your hash, not the name of a var you want to use as key. Moreover, bonding in your yaml structure is already a list that you access directly. There is not need to use the list filter in this case.

The correct syntax to create your loop is either one of:

  • with_items: "{{ hostvars[inventory_hostname]['bonding'] }}"
  • with_items: "{{ hostvars[inventory_hostname].bonding }}"

Upvotes: 0

Related Questions