Ansible with_items doesn't print whole item?
Solution 1:
Ansible 2.2 has loop_control.label
for this.
- name: Secure ssl keys
file: path={{ item.path }} user=root group=root mode=600
with_items: secure_ssl_keys_result.files
loop_control:
label: "{{ item.path }}"
- Found via: https://stackoverflow.com/a/42832731/799204
- Documentation: http://docs.ansible.com/ansible/playbooks_loops.html#loop-control
Solution 2:
Method 1
Use
secure_ssl_keys_result.files|map(attribute='path')|list
It will return a list of paths:
['/etc/ssl../', '/etc/ssl/.../']
Your whole task would become:
- name: Secure ssl keys
file: path={{ item }} user=root group=root mode=600
with_items: secure_ssl_keys_result.files|map(attribute='path')|list
Beware that you can only select a single attribute, it is not possible to use attribute=['path', 'mode']
or similar.
Method 2
I thought of using extract to be able to fetch multiple keys (because it is sometimes necessary to have a second key for a when
condition), but didn't manage to do it, as I would need to map the list of dicts, then map the list of keys over the specific dict, which doesn't seem possible, as map only accepts a function name but not a function definition/chained functions. I would be grateful for an suggestion here!
A great idea from the comments (Thanks, Uditha Desilva!):
- name: Secure ssl keys file: path={{ item.0 }} mode=600 owner={{ item.1 }}
with_together:
- secure_ssl_keys_result.files|map(attribute='path')|list
- secure_ssl_keys_result.files|map(attribute='uid')|list
Method 3
Alternatively, a custom filter like this could be used (that's what I did before I found out about map
):
from ansible import errors
import re
def cleandict(items, keepkeys):
try:
newitems = []
if not isinstance(items, list):
items = [items]
if not isinstance(keepkeys, list):
keepkeys = [keepkeys]
for dictionary in items:
newdictionary = {}
for keepkey in keepkeys:
newdictionary[keepkey] = dictionary.get(keepkey)
newitems.append(newdictionary)
return newitems
except Exception, e:
raise errors.AnsibleFilterError('split plugin error: %s' % str(e) )
#raise errors.AnsibleFilterError('split plugin error: %s, string=%s' % str(e),str(items) )
class FilterModule(object):
''' A filter to split a string into a list. '''
def filters(self):
return {
'cleandict' : cleandict
}
ansible.cfg
:
filter_plugins = ~/.ansible/plugins/filter_plugins/:/usr/share/ansible_plugins/filter_plugins
Solution 3:
You can't. It's either all or nothing (via no_log: True
)