2016-03-24 42 views
3

我想循环一个列表,它存储在一个字典中,它是另一个列表的一部分。我的剧本是这样的:在嵌套中的多个嵌套循环

--- 
- 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 

现在我在遍历列表我栈,ansible好像不支持真正的嵌套,只是两个嵌套循环的几个预定义的结构。

我会需要这样的东西(不工作):

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

或(错误语法的子元素):

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

我已经尝试过使用冗余列表:

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

如你所见,它已经开始变得丑陋item.item

这将需要像

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 

,或者如果它不需要是列表,以便能够迭代它甚至item.hostname而不是元组(实际上列出)。

这将是非常好的有一些方法来指定循环嵌套,而不是使用预制过滤器,如with_subelements

回答

1

您是否尝试过使用“with_nested”?您可以查看Ansible documentation

这可能会实现:

- 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 
+0

我想''with_nested''并得到了与复杂item.item.item链similiar奇怪的结果(也许在指数之间)打开发行前。问题是使用嵌套列表的列表,并且我意识到ansible并不真正支持嵌套列表,但对于最常见的嵌套(两层,使用散列,)只有几个实现,但不支持任意嵌套。我还没有测试过你的答案,因为我目前不同地解决了这个问题(使用外部脚本在运行完成后复制内容)。 – allo

+0

这三个层不在副本中,而是在重新启动部分,需要嵌套:''对于域中的域:对于host.hosts中的主机:对于host.services中的服务:重新启动服务'。我的问题中的例子已经平淡一些以避免这些问题,但用纯粹的方法来解决这个问题仍然很难。除了外部脚本之外,其他可能性可能会使用两个剧本或编写自定义过滤器,以实现更多嵌套和/或仅解决当前使用情况。 – allo