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

Tags:

Ansible