ansible中的多个嵌套循环

Posted

技术标签:

【中文标题】ansible中的多个嵌套循环【英文标题】:Multiple nested loops in ansible 【发布时间】:2016-07-12 10:03:38 【问题描述】:

我正在尝试遍历一个列表,该列表存储在一个字典中,该字典是另一个列表的一部分。我的剧本是这样的:

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

【讨论】:

在打开问题之前,我尝试了with_nested,并通过复杂的 item.item.item 链(可能是中间的索引)得到了类似的奇怪结果。问题在于使用嵌套列表列表,我意识到 ansible 并不真正支持嵌套列表,但只有一些最常见嵌套的实现(两层,使用哈希,...)但不支持任意嵌套。我还没有测试你的答案,因为我目前以不同的方式解决了这个问题(运行 ansible 后使用外部脚本复制内容)。 这三层不是在copy处,而是在restart部分,需要嵌套:''for domain in domain: for host in domain.hosts: for service in host.services:重启服务``。为了避免这些问题,我的问题中的示例已经有点扁平化了,但是用纯 ansible 来做这件事仍然很讨厌。除了外部脚本之外,其他可能性可能是使用两个剧本或为 ansible 编写自定义过滤器,这允许更多嵌套和/或仅解决当前用例。

以上是关于ansible中的多个嵌套循环的主要内容,如果未能解决你的问题,请参考以下文章

Ansible嵌套循环,如何基于外部变量设置内部循环变量

如何根据嵌套循环中的多个变量报告进度(对于进度条)?

Python中的嵌套循环

python中的多个嵌套循环等效替换

嵌套多个“for”循环

R中的存储问题。替代用于创建矩阵数组和多个绘图的嵌套循环