Is it possible to convert a list of lists/dicts to a list of strings using a formatting string in Ansible / Jinja2?
I understand I can do something like:
{{["First: %d", "Second: %d"] | map("format", 1) | join(", ") }}
To get First: 1, Second 1
.
Would it be possible to do something like
{{[[1, 1], [2, 2]] | map("format", "Num %d, %d") | join(", ") }}
and result in Num 1, 1, Num 2, 2
?
It is not possible with the core format
filter. But if you are willing to write a few lines of python, you can easily solve this with a custom filter. I went to the simplest for demo, you would probably have to harden the code and fix edge cases for a real life use. You may want to have a look at the plugin development documentation for more info.
For this example, I will save the custom file in the filter_plugins
directory adjacent to my test playbook. You can save it in a collection or a role if you want to share across different projects.
In filter_plugins/my_format_filters.py
def reverse_format(param_list, format_string):
"""format format_sting using elements in param_list"""
return format_string % tuple(param_list)
class FilterModule(object):
"""my format filters."""
def filters(self):
"""Return the filter list."""
return {
'reverse_format': reverse_format
}
Then the following example playbook:
---
- name: custom filter demo
hosts: localhost
gather_facts: false
tasks:
- name: map custom reverse_format filter
debug:
msg: '{{ item.replacements | map("reverse_format", item.format) | join(", ") }}'
loop:
- replacements:
- [1, 1]
- [2, 2]
format: "Num %d, %d"
- replacements:
- ['Jack', 'John', 12]
- ['Mary', 'Alicia', 34]
format: "%s owes %s %d€"
gives:
PLAY [custom filter demo] **************************************************************************************************************************************************************************************************************
TASK [map custom reverse_format filter] ************************************************************************************************************************************************************************************************
ok: [localhost] => (item={'replacements': [[1, 1], [2, 2]], 'format': 'Num %d, %d'}) => {
"msg": "Num 1, 1, Num 2, 2"
}
ok: [localhost] => (item={'replacements': [['Jack', 'John', 12], ['Mary', 'Alicia', 34]], 'format': '%s owes %s %d€'}) => {
"msg": "Jack owes John 12€, Mary owes Alicia 34€"
}
PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0