ansible: how to iterate over all registered results?

27,870

Solution 1

Looping over the results in an array (denoted by the []), would be done as

with_items: somelist

or if it's a dict that contains a list, as in this case

with_items: log_dir.results

note this can also be written

with_items: log_dir['results']

so in your task

- name: Check if log directory exists - Step 2
  fail: msg="Log directory does not exists or it is not a symlink."
  failed_when: >
    item.stat.islnk is not defined
    or item.stat.islnk != true
    or item..stat.lnk_source != "{{ wl_base }}/logs/{{ wl_dom }}/{{ item.1 }}"
  with_items: log_dir.results

More information and examples is available in http://docs.ansible.com/playbooks_loops.html#standard-loops.

The main thing here is that you're wanting to access only part of the registered variable.

Solution 2

My debug output:

{
"dkim_key.results": [
    {
        "changed": false,
        "invocation": {
            "module_args": "path=/etc/opendkim/keys/accept.example.com/mail.private get_md5=no",
            "module_name": "stat"
        },
        "item": "accept.example.com",
        "stat": {
            "atime": 1427461574.5667424,
            "checksum": "c882abaabvc66257555929f6290480a409d1",
            "ctime": 1427461575.0307424,
            "dev": 64770,
            "exists": true,
            "gid": 119,
            "inode": 521115,
            "isblk": false,
            "ischr": false,
            "isdir": false,
            "isfifo": false,
            "isgid": false,
            "islnk": false,
            "isreg": true,
            "issock": false,
            "isuid": false,
            "mode": "0600",
            "mtime": 1427461574.5947425,
            "nlink": 1,
            "pw_name": "opendkim",
            "rgrp": false,
            "roth": false,
            "rusr": true,
            "size": 887,
            "uid": 110,
            "wgrp": false,
            "woth": false,
            "wusr": true,
            "xgrp": false,
            "xoth": false,
            "xusr": false
        }
    },
    {
        "changed": false,
        "invocation": {
            "module_args": "path=/etc/opendkim/keys/test.example.com/mail.private get_md5=no",
            "module_name": "stat"
        },
        "item": "test.example.com",
        "stat": {
            "exists": false
        }
    }
]
}

Found the solution for a similar problem as follows:

- name: DKIM | Generate signing key
  shell: opendkim-genkey -s {{ postfix.dkim_selector }} -d {{ item.item }} -D /etc/opendkim/keys/{{ item.item }}
  with_items: dkim_key.results
  when: not item.stat.exists
  notify: restart opendkim
  tags:
    - postfix
    - dkim

Using the dkim_key.results and a list to iterate over and then check against that list with item.stat.exists. Lastly getting the actual item via item.item

Share:
27,870
dawud
Author by

dawud

Experience Indra Senior System Engineer Indra March 2009 – Present Alcobendas Area, Spain Euroquality System Administrator Euroquality January 2009 – March 2009 Madrid Area, Spain Expectra System Administrator Expectra June 2007 – January 2009 Madrid Area, Spain Languages English Professional working proficiency Spanish Native or bilingual proficiency Certifications Zabbix 2.0 Certified Specialist ZABBIX SIA, License CS1301-19 January 2013 – Present Education Complutense University of Madrid Philosophy, 2000 - 2002 Biology, 1995 - 1998 I.E.S. Parla II BUP & COU, 1990 - 1994 C.P. Pablo Picasso EGB, 1982 - 1989 Interests GNU/Linux OpenBSD IT security SELinux climbing hiking

Updated on March 28, 2020

Comments

  • dawud
    dawud about 4 years

    Given the following playbook:

    ---
    - name: Check if log directory exists - Step 1
      stat: path="{{ wl_base }}/{{ item.0.name }}/{{ wl_dom }}/servers/{{ item.1 }}/logs" get_md5=no
      register: log_dir
      with_subelements:
        - wl_instances
        - servers
    
    - name: Check if log directory exists - Step 2
      fail: msg="Log directory does not exists or it is not a symlink."
      failed_when: >
        log_dir.results[0].stat.islnk is not defined
        or log_dir.results[0].stat.islnk != true
        or log_dir.results[0].stat.lnk_source != "{{ wl_base }}/logs/{{ wl_dom }}/{{ item.1 }}"
      with_subelements:
        - wl_instances
        - servers
    

    that is using the following vars:

    ---
    wl_instances:
      - name: aservers
        servers:
          - AdminServer
      - name: mservers
        servers:
           - "{{ ansible_hostname }}"
    

    the second task currently only uses one of the two possible results (results[0]).

    My question is: how could I iterate over all available items stored in log_dir.results?

    A sample output debug:hostvars[inventory_hostname] follows:

        "log_dir": {
            "changed": false,
            "msg": "All items completed",
            "results": [
                {
                    "changed": false,
                    "invocation": {
                        "module_args": "path=\"/path/to/servers/aservers/domain/AdminServer/logs\" get_md5=no",
                        "module_name": "stat"
                    },
                    "item": [
                        {
                            "name": "aservers"
                        },
                        "AdminServer"
                    ],
                    "stat": {
                        ...
                        "lnk_source": "/path/to/logs/domain/AdminServer",
                        ...
                    }
                },
                {
                    "changed": false,
                    "invocation": {
                        "module_args": "path=\"/path/to/servers/mservers/domain/servers/some_hostname/logs\" get_md5=no",
                        "module_name": "stat"
                    },
                    "item": [
                        {
                            "name": "mservers"
                        },
                        "some_hostname"
                    ],
                    "stat": {
                        ...
                        "lnk_source": "/path/to/logs/domain/some_hostname",
                        ...
    
    • tvb
      tvb about 9 years
      Did you find a solution?
    • dawud
      dawud about 9 years
      Not for the iteration, I switched to a data structure suitable for a with_dict iteration.
    • tvb
      tvb about 9 years
      Found a solution that worked for me, posted it below.
  • tvb
    tvb about 9 years
    Hi Halberom, thank you for answering my call for help on IRC. I had to leave IRC before I could talk to you. Found the same solution before I saw your post. I will upvote yours as the correct answer. Thanks again!
  • Stanislav
    Stanislav over 6 years
    should not it be fail: ... when: ... instead of fail: ... failed_when:
  • JamStar
    JamStar about 6 years
    quick note. since ansible v2.2, with_items requires explicit jinja2 wrapping so this would now be with_items: "{{ log_dir.results }}"