Multiple nested loops in ansible

2019-07-07 01:55发布

问题:

I am trying to loop over a list, which is stored in a dict, which is part of another list. my playbook looks like this:

---
- hosts: all 
  vars:
    copy_certs:
      - { domain: 'domainname', copy_to: ['/tmp/foo', '/tmp/bar'], restart: [["mailhost", "postfix"], ["mailhost", "dovecot"]] }
      - { domain: 'domainname2', copy_to: ['/tmp/foo2', '/tmp/bar2'], restart: [["mail.lxc", "postfix"]] }
  tasks:
[...]
    - name: Copy Private Key 
      register: copied_key
      copy: src=/etc/letsencrypt/live/{{ item.0.domain }}/privkey.pem dest="{{ item.1 }}/"
      with_subelements:
        - copy_certs
        - copy_to
    - name: Debug (here should be delegates to "item.restart.NUM.0" to restart "item.restart.NUM.1" with_subelements: ...)
      debug: var=item
      with_items: copied_key.results

Now i am stack at iterating over the lists, as ansible seems not to support real nesting, but just a few predefined structures for two nested loops.

i would need something like (does not work):

with_subelements:
  - copied_key.results
  - item.domain.restart

or (wrong syntax for subelements):

with_subelements:
  - copied_key.results
  - item.domain
  - restart

I already tried to use an redundant list:

vars:
  restart_services:
    domainname: [["mailhost", "postfix"]]
tasks:
  - name: Debug
  debug: var=restart_services[item.item.0.domain]
  with_items: copied_key.results

as you see it already starts being ugly with item.item.

It would need something like

  register: [to_restart for to_restart in item['restart']] as services_to_rstart
- debug: var=item # item.0 = hostname item.1 = servicename
  with_items: services_to_restart

or if it does not need to be lists to be able to iterate over it even item.hostname instead of tuples (actually lists).

It would be really good to have some way to specify loops with nesting instead of using premade filters like with_subelements.

回答1:

Have you tried using "with_nested"? You can check out the Ansible documentation.

This might work:

- name: Copy Private Key
  register: copied_key
  copy: src=/etc/letsencrypt/live/{{ item[0].domain }}/privkey.pem dest="{{ item[1] }}/"
  with_nested:
    - copy_certs
    - copy_certs.copy_to


标签: loops ansible