I have a fairly large inventory data structure from which I need to extract a value within a playbook. I’m wondering if this is possible with native Ansible, for example, by directly applying a filter plugin in the playbook or so…
Here is my data structure represented as YAML for illustration:
I need the IP address (here “192.0.2.1”) from the key “addr”.
Short summary of the above data structure:
the list “interfaces” has an element with a dict
this dict has a key of “name” that must be of the value “lo0”
it has also a key “ipaddr” that contains a list
this list contains a dictionary that has the key “family”
that key is a dict that has a key “label” that must be of the value “IPv4.”
As far as I know I could write a custom filter plugin for this, but I would prefer to have it natively within the playbook for better portability and understanding by operational colleagues.
{{ hostvars[inventory_hostname].interfaces }} is the same as {{ interfaces }}.
With that simplification, the expression you want is… complicated. Here it is, built up one step at a time.
Thanks a lot for the great solutions. I’d prefer Todd’s ‘native’ solution if it didn’t require so many individual steps. I’ve installed JMESPath and got it to work with the following task and expression:
tasks:
- name: Setting routerid to value of ipv4 loopback address
ansible.builtin.set_fact:
routerid: "{{ interfaces | community.general.json_query('[?name == `lo0`].ipaddr[] | [?family.label == `IPv4`].addr') }}"
I think I need to ponder a bit more about this really efficient looking expression…
If by steps you mean the five filters in the pipeline, that’s the nature of the beast.
But if by steps you mean playbook tasks, all but the last one are there just so you can see what each stage in the pipeline produces. It’s the expression in the last debug step that solves your initial ask.
My problem with a json_query solution is, now you have to grok both Jinja2 and JMESPath queries.
Oh, mea culpa, what nonsense I’ve written. I’ve got a lot on my plate, sorry Todd. I believe the native solution, in its expression, is on par with the JSON query, obviously!
Now I’m torn because this decision will likely set the direction for hundreds of similar requests.
I wonder which implementation is more efficiently handled in software and executed in hardware. Perhaps I should conduct some performance tests between them.
Compared to all the things that have to work – on the controller and any remote hosts – for any playbook of any significance at all, you could optimize either of those expressions down to a single cycle and not notice any improvement.
Far more important is the number of seconds/minutes you and those who follow will have to spend looking at however you end up spelling the solution to this and other problems.
Okay, maybe I exaggerated. But in 100,000,000 runs you’ll not gain back the time it’s taken you to read this message.
OTOH, familiarity with JMESPath is certainly worthwhile, and Jinja2 is expressly “limited as a feature”. (I’ve never bought the “not designed to program with” argument, from Jinja2, Ansible, or elsewhere. It’s trotted out whenever someone pushes a tool beyond what the inventors envisioned. It’s the same as Apple’s old argument that color wasn’t important — until they released a color Mac. Hm.)