Reputation: 1658
Here's something I think should be straight-forward in Ansible, but I'm having trouble finding a canonical best practice.
In Ansible, I have a list of dicts in YAML:
config:
- id: x
value: X
- id: y
value: Y
I want to generate a list of strings that can be passed as a whole to the mysql_query module.
I've tried various elegant ways of doing this using Ansible filters, but that best I've come up with is to generate a list of newline-separate strings in a single template that iterates over config
and then trim | split('\n')
the resulting single string.
Template:
{% for item in config %}
{{ item.id }} => {{ item.value }}
{% endfor %}
Playbook task:
set_fact:
converted_items: "{{ lookup('template', './template.j2') | trim | split('\n') }}"
But this feels like a kludge.
What am I missing here?
[Note this is a canned example, to keep things simple.]
Upvotes: 1
Views: 5550
Reputation: 17017
if you want to transform list of dicts to list of strings, just use loop and union:
- name: vartest
hosts: localhost
vars:
config:
- id: x
value: X
- id: y
value: Y
tasks:
- name: transform value
set_fact:
result: "{{ result | default([]) | union([item.id ~ ' => ' ~ item.value]) }}"
loop: "{{ config }}"
- name: display result
debug:
var: result
equivalent of union: result | default([]) + [item.id ~ ' => ' ~ item.value]
result:
ok: [localhost] => {
"result": [
"x => X",
"y => Y"
]
}
Upvotes: 1
Reputation: 68074
You don't have to use a file. Put the Jinja template into the local vars, e.g.
- set_fact:
converted_items: "{{ _converted_items|trim|split('\n') }}"
vars:
_converted_items: |
{% for item in config %}
{{ item.id }} => {{ item.value }}
{% endfor %}
gives
converted_items:
- x => X
- y => Y
There are many options of how to transform the data, e.g. the task below gives the same result
- set_fact:
converted_items: "{{ _keys|zip(_vals)|map('join', ' => ')|list }}"
vars:
_keys: "{{ config|map(attribute='id')|list }}"
_vals: "{{ config|map(attribute='value')|list }}"
Upvotes: 1