双循环 Ansible

问题描述 投票:0回答:4

我有一个这样的物体

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

我想创建以下文件

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

但我不知道如何使用

with_items

进行双循环
ansible
4个回答
39
投票

查看

with_subelements
中的 Ansible 循环文档

  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

输出非常不言自明,第二个循环按照您需要的方式迭代值:

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 

21
投票

事实上你不能。 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

再次强调,这在当前版本(1.9.2)的 Ansible 中不起作用。该功能因引起一些问题而被删除,但将在 Ansible 2.0 中再次受到支持,因此当您使用 github 的 devel 分支时,它应该可用。

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

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

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

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

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

比如说

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

0
投票
使用 Jinga2 语法的双循环

制作基本双循环的最简单方法之一

- name: FILE remove some files ansible.builtin.file: path: "/Users/{{ item[0] }}/{{ item[1] }}" state: absent loop: "{{ [ 'user1', 'user2' ] | product(['file1', 'file2', 'file3']) | list }}"
    
© www.soinside.com 2019 - 2024. All rights reserved.