Reputation: 1
How can we create a code as below?
- name: TEST1
set_fact:
list_a: "{{ list_a + [item.json.SearchResult.resources] }}"
with_items:
- "{{ source_list.results[0] }}"
- "{{ source_list.results[1] }}"
- "{{ source_list.results[x] }}"
... (unknown how many items in result from API)
vars:
list_a: []
source_list.results[x]
comes from an API result. The reason why I need to create an array is that the number of API result is maximum 100. But there are over 500 items.
Upvotes: 0
Views: 3606
Reputation: 44615
You are taking this the wrong way. Simply extract the attribute you need from each result using the map(attribute=x)
Jinja2 filter.
Since you did not provide an example data structure, I inferred below that:
ansible.builtin.uri
in a loop to get batches of 100 results which are returned as a list in the SearchResult.ressources
fieldresources
are at top level- name: Show my list of single attributes
ansible.builtin.debug:
var: "source_list.results
| map(attribute='json.SearchResult.resources') | flatten"
You actually don't need to set_fact
:
loop
or a module param....) or eventually declare this in a var at task level.source_list
var. In that case, just add a default value to prevent an error if API was not yet called.Example for the second case above in this pseudo playbook
---
- hosts: localhost
gather_facts: false
vars:
list_a: "{{ source_list.results | d([])
| map(attribute='json.SearchResult.resources') | flatten }}"
tasks:
- name: "This will return an empty list (i.e. [])
as we did not populate source_list yet"
ansible.builtin.debug:
var: list_a
- name: Call our API and register source_list
ansible.builtin.uri:
uri: https://my.api.com/api/v1/some/endpoint
# [... more parameters here ... ]
loop: "{{ my_list_of_ressources }}"
register: source_list
- name: "This will now return a populated list
after calling the API and registering source_list"
ansible.builtin.debug:
var: list_a
Now, to still give a direct answer to your initial question: you can construct that list iteratively inside a set_fact
task. This is definitely not efficient as it involves a task running inside a loop (both unneeded as demonstrated above) and possibly on multiple hosts in your play. But for learning purpose, here it is:
- name: very inefficient way to get the same result as above
set_fact:
list_a: "{{ list_a | d([]) + item.SearchResult.resources }}"
loop: "{{ source_list.results }}"
Upvotes: 2
Reputation: 1
After reading @Zeitounator's answer, I realized I was taking this the wrong way. I used the idea in the answer (json query
and flatten
) and I changed my task to the below which works as expected.
- name: Create ID list from API result data
set_fact:
list_a: "{{ source_list | json_query('results[*].json.SearchResult.resources[*].id') | flatten }}"
- name: API get again with id
uri:
url: "{{ request_url }}/{{ item }}"
...
register: result_data
with_items:
- "{{ list_a }}"
Upvotes: 0