Question:
I want to add keys to a dictionary when using set_fact with with_items. This is a small POC which will help me complete some other work. I have tried to generalize the POC so as to remove all the irrelevant details from it.
When I execute following code it is shows a dictionary with only one key that corresponds to the last item of the with_items. It seems that it is re-creating a new dictionary or may be overriding an existing dictionary for every item in the with_items. I want a single dictionary with all the keys.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
--- - hosts: localhost connection: local vars: some_value: 12345 dict: {} tasks: - set_fact: { dict: "{ {{ item }}: {{ some_value }} }" } with_items: - 1 - 2 - 3 - debug: msg="{{ dict }}" |
Answer:
Use a filter plugin.
First, make a new file in your ansible base dir called filter_plugins/makedict.py
.
Now create a new function called “makedict” (or whatever you want) that takes a value and a list and returns a new dictionary where the keys are the elements of the list and the value is always the same.
1 2 3 4 |
class FilterModule(object): def filters(self): return { 'makedict': lambda _val, _list: { k: _val for k in _list } } |
Now you can use the new filter in the playbook to achieve your desired result:
1 2 3 4 5 6 7 8 9 10 |
- hosts: 127.0.0.1 connection: local vars: my_value: 12345 my_keys: [1, 2, 3] tasks: - set_fact: my_dict="{{ my_value | makedict(my_keys) }}" - debug: msg="{{ item.key }}={{ item.value }}" with_dict: "{{my_dict}}" |
You can customize the location of the filter plugin using the filter_plugins
option in ansible.cfg
.