双循环Ansible

Ajo*_*uve 19 ansible ansible-playbook

我有一个这样的对象

objs:
    - { key1: value1, key2: [value2, value3] }
    - { key1: value4, key2: [value5, value6] }
Run Code Online (Sandbox Code Playgroud)

我想创建以下文件

value1/value2
value1/value3
value4/value5
value4/value6
Run Code Online (Sandbox Code Playgroud)

但我不知道如何使用双循环 with_items

Vor*_*Vor 23

是.您可以.

看看with_subelements这里http://docs.ansible.com/ansible/playbooks_loops.html#nested-loops

  1. 您需要创建一个文件夹:
  2. 迭代objs并创建文件:

这是一个例子:

---

- hosts: localhost
  gather_facts: no
  vars:
    objs:
      - { key1: value1, key2: [ value2, value3] }
      - { key1: value4, key2: [ value5, value6] }
  tasks:

    - name: create directories
      file: path="{{ item.key1 }}"  state=directory
      with_items:
        objs

    - name: create files
      file: path="{{ item.0.key1 }}/{{ item.1 }}"  state=touch
      with_subelements:
        - objs
        - key2
Run Code Online (Sandbox Code Playgroud)

输出非常自我解释,第二个循环以您需要的方式遍历值:

PLAY [localhost] ************************************************************** 

TASK: [create files] ********************************************************** 
changed: [localhost] => (item={'key2': ['value2', 'value3'], 'key1': 'value1'})
changed: [localhost] => (item={'key2': ['value5', 'value6'], 'key1': 'value4'})

TASK: [create files] ********************************************************** 
changed: [localhost] => (item=({'key1': 'value1'}, 'value2'))
changed: [localhost] => (item=({'key1': 'value1'}, 'value3'))
changed: [localhost] => (item=({'key1': 'value4'}, 'value5'))
changed: [localhost] => (item=({'key1': 'value4'}, 'value6'))

PLAY RECAP ******************************************************************** 
localhost                  : ok=2    changed=2    unreachable=0    failed=0 
Run Code Online (Sandbox Code Playgroud)

  • 请注意,从 Ansible v2.7 开始,最好使用 [`loop`](https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#comparing-loop-and-with) 构造[`subelements` 过滤器](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#subelements-filter) 而不是 `with_X` 构造。有关如何迁移的信息,请参阅循环文档。 (3认同)
  • 当我尝试这个时,我收到一个错误。我认为 `with_subelements` 下的第一项需要 `{{ }}`,即 `with_subelements: ["{{ objs }}", "key2"]` (2认同)

udo*_*dan 11

实际上你做不到.Ansible中的循环是一维的.有一个技巧曾经在以前的版本中工作,并将再次在Ansible 2.0中工作:

你可以将一个循环与一个include语句放在一起,并且在yml中你有第二个循环.所以沿着这些方向:

main.yml:

- include: nested_loop.yml obj={{ item }}
  with_items: objs
Run Code Online (Sandbox Code Playgroud)

nested_loop.yml:

- name: create files
  file: path={{obj.key1 }}/{{ item }} state=touch
  with_items: obj.key2
Run Code Online (Sandbox Code Playgroud)

同样,这在Ansible的当前版本(1.9.2)中不起作用.该功能被删除,因为它引起了一些问题,但将在Ansible 2.0中再次支持,因此当您使用来自github的devel分支时它应该可用.

您可以使用以下命令从github源安装:

git clone https://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup
sudo make install
Run Code Online (Sandbox Code Playgroud)


小智 8

添加到 udondan 的答案(没有代表在上面发表评论):

使用 with_items 会导致意想不到的结果,因为外循环和内循环共享一个公共变量“item”。

您将需要使用“loop_control”来防止变量冲突。

例如

- include: nested_loop.yml obj={{ outside_item }}
  with_items: objs
  loop_control:
    loop_var: outside_item
Run Code Online (Sandbox Code Playgroud)