双循环Ansible

时间:2015-07-22 14:47:33

标签: ansible ansible-playbook

我有一个像这样的对象

objs:
    - { key1: value1, key2: [value2, value3] }
    - { key1: value4, key2: [value5, value6] }

我想创建以下文件

value1/value2
value1/value3
value4/value5
value4/value6

但我不知道如何使用with_items

进行双循环

3 个答案:

答案 0 :(得分:22)

是。您可以。

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

查看with_subelements
  1. 您需要创建一个文件夹:
  2. 迭代objs并创建文件:
  3. 以下是一个例子:

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

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

    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 
    

答案 1 :(得分:8)

事实上,你不能。 Ansible中的循环是一维的。有一个技巧曾经在以前的版本中工作,并将再次在Ansible 2.0中使用:

你可以将一个循环与include语句放在一起,并且在yml中你有第二个循环。所以有这样的话:

<强> main.yml:

- include: nested_loop.yml obj={{ item }}
  with_items: objs

<强> nested_loop.yml:

- name: create files
  file: path={{obj.key1 }}/{{ item }} state=touch
  with_items: obj.key2

同样,这在Ansible的当前版本(1.9.2)中不起作用。该功能已被删除,因为它会导致一些问题但会在Ansible 2.0中再次受到支持,所以当您使用devel branch from github时它应该可用。

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

git clone https://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup
sudo make install

答案 2 :(得分:1)

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

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

您将希望使用“ loop_control”来防止变量冲突。

例如

- include: nested_loop.yml obj={{ outside_item }}
  with_items: objs
  loop_control:
    loop_var: outside_item