# Wildcards in ansible\_facts

**URL:** <https://forum.ansible.com/t/wildcards-in-ansible-facts/8260>\
**Category:** Get Help\
**Tags:** playbook, netbox, inventory\
**Created:** [September 4, 2024, 2:36pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260 "2024-09-04T14:36:31Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![sam\_karateman](https://avatars.discourse-cdn.com/v4/letter/s/c5a1d2/32.png) [@sam\_karateman](https://forum.ansible.com/u/sam_karateman)\
**Post date:** [September 4, 2024, 2:36pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/1 "2024-09-04T14:36:31Z")

</div>

Hello,

I’m attempting to loop over numerous network interfaces and send them to our NetBox instance. Unfortunately, due to the disparate types of servers and network interfaces that are provided, I would like to be able to use wildcards to loop over all interfaces of certain types. So far I have attempted the following:

```auto
    - name: Write interfaces and addresses
      include_tasks:
        file: interfaces.yml
      loop:
        - "{{ ansible_facts['ansible_eth*'] }}"
        - "{{ ansible_facts['ansible_'+eno*] }}"
        - "{{ ansible_facts['ansible_'+enp24s0f*] }}"

```

Unsurprisingly, ansible isn’t happy when I tried to do so:

```auto
TASK [Write interfaces and addresses] ********************************************************************************************
fatal: [<hostname>]: FAILED! => {"msg": "'dict object' has no attribute 'ansible_eth*'. 'dict object' has no attribute 'ansible_eth*'"}

```

I’m looking for guidance on how to best iterate over the interfaces. Any advice is greatly appreciated. If it’s relevant, ansible version info is below:

```auto
ansible [core 2.16.6]
  config file = /home/user/project-hpc-netbox-migration/ansible.cfg
  configured module search path = ['/home/user/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/rci/miniconda3/envs/ansible/lib/python3.12/site-packages/ansible
  ansible collection location = /home/user/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/rci/miniconda3/envs/ansible/bin/ansible
  python version = 3.12.3 | packaged by Anaconda, Inc. | (main, May 6 2024, 19:46:43) [GCC 11.2.0] (/opt/rci/miniconda3/envs/ansible/bin/python)
  jinja version = 3.1.4
  libyaml = True

```

---

<div class="post-metadata">

**Author:** ![dnmvisser](https://avatars.discourse-cdn.com/v4/letter/d/8e8cbc/32.png) [@dnmvisser](https://forum.ansible.com/u/dnmvisser)\
**Post date:** [September 4, 2024, 5:24pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/2 "2024-09-04T17:24:18Z")

</div>

Hii

> > ![](https://us1.discourse-cdn.com/ansible/original/2X/4/40ebec9b7e56b7a1cf66d19edb5c6f4cc2ac6e61.png "sam\_karateman") | [sam\_karateman](http://forum.ansible.com/u/sam_karateman)  
> > September 4 |
> > 
> > - | - |
> 
> Hello,
> 
> I’m attempting to loop over numerous network interfaces and send them to our NetBox instance. Unfortunately, due to the disparate types of servers and network interfaces that are provided, I would like to be able to use wildcards to loop over all interfaces of certain types. So far I have attempted the following:
> 
> ```auto
> - name: Write interfaces and addresses
> include_tasks:
> file: interfaces.yml
> loop:
> - "{{ ansible_facts['ansible_eth*'] }}"
> - "{{ ansible_facts['ansible_'+eno*] }}"
> - "{{ ansible_facts['ansible_'+enp24s0f*] }}"
> 
> ```
> 
> Unsurprisingly, ansible isn’t happy when I tried to do so:
> 
> ```auto
> TASK [Write interfaces and addresses] ********************************************************************************************
> fatal: [<hostname>]: FAILED! => {"msg": "'dict object' has no attribute 'ansible_eth*'. 'dict object' has no attribute 'ansible_eth*'"}
> 
> ```
> 
> I’m looking for guidance on how to best iterate over the interfaces. Any advice is greatly appreciated.

Try looping over this:

loop: “{{ ansible\_facts.interfaces | select(‘search’, ‘(eth|eno|enp24s0f)\d+’) }}”

That is a regex there, you may have to tweak it a bit further for your situation.

Dick

---

<div class="post-metadata">

**Author:** ![mayur189](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/mayur189/32/4641_2.png) [@mayur189](https://forum.ansible.com/u/mayur189)\
**Post date:** [September 5, 2024, 12:01pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/3 "2024-09-05T12:01:24Z")

</div>

As a best practice you first filter facts using set\_fact module using filters and iterate over the that variable or list of facts. loop matching the exact attribute name from facts.

ansible.builtin.set\_fact:  
my\_loop\_facts: “{{ ansible\_facts[‘interfaces’] | select(‘search’, ‘^eth|^eno|^enp24s0f’) | list }}”

and then iterate over my\_loop\_facts variable.  
loop:  
my\_loop\_facts

-Mayur

---

<div class="post-metadata">

**Author:** ![sam\_karateman](https://avatars.discourse-cdn.com/v4/letter/s/c5a1d2/32.png) [@sam\_karateman](https://forum.ansible.com/u/sam_karateman)\
**Post date:** [September 16, 2024, 3:58pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/4 "2024-09-16T15:58:25Z")

</div>

I was able to get it working for the lookup based on the replies, but I’m having trouble referencing the variable from within ansible\_facts. I would like to do something like this:

```auto
  when:
    - ansible_facts[\"{{ item }}\"][active] is true

```

but I’m not sure of what the correct syntax would be for referencing a variable from within the ansible\_facts variable. Would anybody have a recommendation?

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [September 17, 2024, 5:14pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/5 "2024-09-17T17:14:42Z")

</div>

`when:` expressions are already in a Jinja context, so you never need (or want) mustaches in them.

With zero testing, assuming you’re on the right track, the expression you show above would be spelled like this:

```yaml
when:
  - ansible_facts[item]['active'] | default(false) | bool

```

And if that doesn’t work, we can make up something else. `:)`

---

<div class="post-metadata">

**Author:** ![sam\_karateman](https://avatars.discourse-cdn.com/v4/letter/s/c5a1d2/32.png) [@sam\_karateman](https://forum.ansible.com/u/sam_karateman)\
**Post date:** [October 4, 2024, 7:04pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/6 "2024-10-04T19:04:48Z")

</div>

I didn’t want to leave this hanging, but this is what ended up working for me:

```auto
    - name: Set interface names
      ansible.builtin.set_fact:
        interface_list: "{{ ansible_facts.interfaces | select('search', '\\A(eth|eno|enp)') | list }}"

```

And in another playbook for the writing of the interfaces:

```auto
  - name: Write interfaces
    local_action:
      module: netbox.netbox.netbox_device_interface
      netbox_url: "{{ lookup('env', 'NETBOX_API') }}"
      netbox_token: "{{ lookup('env', 'NETBOX_TOKEN') }}"
      data:
        name: "{{ ansible_facts[item]['device'] }}"
        label: "{{ ansible_facts[item]['device'] }}"
        device: "{{ ansible_facts['hostname'] }}"
        type: "{{ 'SFP+ (10GE)' if ansible_facts[item]['speed'] == 10000 else '1000BASE-T (1GE)' }}"
        enabled: "{{ true if ansible_facts[item]['active'] is true else false }}"
        mac_address: "{{ ansible_facts[item]['perm_macaddress'] if ansible_facts[item]['perm_macaddress'] is defined else ansible_facts[item]['macaddress'] }}"
        lag: "{{ ansible_facts['bond0'] if item in ansible_facts['bond0']['slaves'] else omit}}"

```

Hopefully this will be useful for anybody else who comes along with a similar issue.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [October 4, 2024, 7:24pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/7 "2024-10-04T19:24:52Z")

</div>

> [@sam\_karateman](#):
>
> ```auto
> type: "{{ 'SFP+ (10GE)' if ansible_facts[item]['speed'] == 10000 else '1000BASE-T (1GE)' }}"
> enabled: "{{ true if ansible_facts[item]['active'] is true else false }}"
> mac_address: "{{ ansible_facts[item]['perm_macaddress'] if ansible_facts[item]['perm_macaddress'] is defined else ansible_facts[item]['macaddress'] }}"
> lag: "{{ ansible_facts['bond0'] if item in ansible_facts['bond0']['slaves'] else omit}}"
> 
> ```

Some of those expressions could be spelled in a more canonical way:

```auto
        type: "{{ ansible_facts[item]['speed'] == 10000 | ansible.builtin.ternary('SFP+ (10GE)', '1000BASE-T (1GE)') }}"
        enabled: "{{ ansible_facts[item]['active'] }}"
        mac_address: "{{ ansible_facts[item]['perm_macaddress'] | default(ansible_facts[item]['macaddress']) }}"
        lag: "{{ item in ansible_facts['bond0']['slaves'] | ansible.builtin.ternary(ansible_facts['bond0'], omit}}"

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [November 3, 2024, 7:25pm UTC](https://forum.ansible.com/t/wildcards-in-ansible-facts/8260/8 "2024-11-03T19:25:34Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
