Ansible 双环可交换

Ansible 双环可交换,ansible,ansible-playbook,Ansible,Ansible Playbook,我有一个这样的物体 objs: - { key1: value1, key2: [value2, value3] } - { key1: value4, key2: [value5, value6] } 我想创建以下文件 value1/value2 value1/value3 value4/value5 value4/value6 但是我不知道如何使用和_items进行双循环,事实上你不能。Ansible中的循环是一维的。有一个技巧在以前的版本中使用,在Ansible 2.0

我有一个这样的物体

objs:
    - { key1: value1, key2: [value2, value3] }
    - { key1: value4, key2: [value5, value6] }
我想创建以下文件

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

但是我不知道如何使用
和_items

进行双循环,事实上你不能。Ansible中的循环是一维的。有一个技巧在以前的版本中使用,在Ansible 2.0中也同样适用:

您可以将一个循环与
include
语句一起使用,在包含的yml中有第二个循环。因此,大致如下:

main.yml:

- include: nested_loop.yml obj={{ item }}
  with_items: objs
- name: create files
  file: path={{obj.key1 }}/{{ item }} state=touch
  with_items: obj.key2
嵌套的_循环。yml:

- include: nested_loop.yml obj={{ item }}
  with_items: objs
- name: create files
  file: path={{obj.key1 }}/{{ item }} state=touch
  with_items: obj.key2
同样,这在Ansible的当前版本(1.9.2)中不起作用。该功能已被删除,因为它导致了一些问题,但Ansible 2.0将再次支持该功能,因此在使用时应该可以使用该功能

您可以从github源安装以下内容:

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

看看这里的子元素

  • 您需要创建目录:
  • 通过
    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
    
    输出是非常自解释的,第二个循环以您需要的方式迭代值:

    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 
    

    补充udondan的回答(没有代表在上面发表评论):

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

    您需要使用“循环控制”来防止变量冲突

    比如说

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

    obj={outside\u item}}在这里甚至不需要,outside\u item可以直接在嵌套的\u loop.yml文件中使用。我使用“include\u tasks”而不是“include”在执行时解析所有变量这里的文档需要注意的是,由于Ansible v2.7,最好将构造与一起使用,而不是将
    与_X
    构造一起使用。请参阅有关如何迁移的文档。当我尝试此操作时,会出现错误。我认为带有{u subelements
    下的第一项需要
    {{}
    ,即带有{u subelements:[“{{objs}}”,“key2”]