I’m trying to create a list of interface names along with their mac addresses from a Debian 11 server, initially, I was trying to get the mac addresses in order only but now I realize I need a list that looks like this:
eth0 <SOME_MAC>
eth1 <SOME_MAC>
...
I want to pass this list as a variable and then use it in the next task to create a 10-persistent-net.link
file in the /etc/systemd/network
directory.
The current task that I’m using is:
- name: Get mac addresses of all interfaces except local
debug:
msg: "{{ ansible_interfaces |
map('regex_replace','^','ansible_') |
map('extract',hostvars[inventory_hostname]) |
selectattr('macaddress','defined') |
map(attribute='macaddress') |
list }}"
As you can see I’m using the debug
module to test out my code and I have no idea how to create my desired list and pass it as a variable.
The above code gives the following result:
ok: [target1] =>
msg:
- 08:00:27:d6:08:1a
- 08:00:27:3a:3e:ff
- f6:ac:58:a9:35:33
- 08:00:27:3f:82:c2
- 08:00:27:64:6a:f8
ok: [target2] =>
msg:
- 08:00:27:34:70:60
- 42:04:1a:ff:6c:46
- 42:04:1a:ff:6c:46
- 08:00:27:d6:08:1a
- 08:00:27:9c:d7:af
- f6:ac:58:a9:35:33
Any help on which module to use to pass the list as a variable and how to create the list in the first place is appreciated.
Kindly Note that I’m using Ansible v5.9.0 and each server may have any number of interfaces, some of them may have ethx
interface name format while others may have enspx
, brx
etc interface format.
UPDATE: Per advice in a comment I must mention that I need one list for each target that will be used in a natural host loop task that will run against each target.
UPDATE 2: As I’m new to Ansible and per my coworker’s advice I was under the impression that a list of interface names along with their MAC addresses separated by space is what I need as a variable to be passed to the next task, however, throughout comments and answers I now realize that I was absolutely heading in the wrong direction. Please accept my apology and blame it on my lack of experience and knowledge of Ansible. In the end, it turned out that a dictionary of interface names and their MAC addresses is what is most suitable for this kind of action in Ansible.
2
Answers
This is how I would do it.
Note that my example uses the
json_query
filter which requirespip install jmespath
on your ansible controller.Which gives running against my localhost:
As you can see, this is showing several interfaces that you might want to filter out in your use case. You can inspect
interfaces_list_raw
and create additional filters to achieve your goal. But at least you get the idea.Get the list of the variables
Get the values of the variables and create a dictionary
Notes
gives
You can see that the output of Jinja is not ordered. Actually, the order is not even persistent when you repeat the task. Use the filter sort if you want to order the lines. For example,
gives