Ansible - 在列表产品上循环时枚举列表(嵌套循环) [英] Ansible - Enumerate list when looping on list product (nested loop)

查看:44
本文介绍了Ansible - 在列表产品上循环时枚举列表(嵌套循环)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 Ansible 中使用嵌套循环(为 10 个用户中的每一个创建 3 个虚拟机"):

I am using a nested loop in Ansible ("create 3 VMs for each of the 10 users"):

  - name: Add hosts to inventory
    add_host:
      name: "{{ '%s-%02d-%02d' | format(vm_prefix, item.0, item.1.number) }}"
      groups: vms
    loop: "{{userlist | product(vms_per_user) | list }}"  

我的问题是 - 我有没有办法获取第二个列表中项目的索引?

My question is - do I have any way of getting the index of an item in the second list?

  - name: Add hosts to inventory
    add_host:
      name: "{{ '%s-%02d-%02d' | format(vm_prefix, item.0, item.1.number) }}"
      groups: vms
      vm_index: "{{ get the index of this particular VM in vms_per_user }}"
    loop: "{{userlist | product(vms_per_user) | list }}"  

我知道 with_indexed_itemsflatten + loop_control.index,但我不知道如何编写它,以便我将获得一个仅在第二个列表上循环的索引,并且每次从 0 重新开始新用户(第一个列表中的每个新元素).

I know about with_indexed_items and flatten + loop_control.index, but I cannot figure out how to write this so that I will get an index that loops only on the second list, and restarts from 0 for every new user (every new element in the first list).

TL;DR - 我正在寻找这个 Python 结构的 ansible 等价物:

TL;DR - I am looking for the ansible equivalent of this Python construct:

for user in users:
  for (index, vm_name) in enumerate(vms_per_user):
     do_something_with user, index, vm_name

谢谢!

推荐答案

如果 Ansible 有一个 enumerate 过滤器,这将非常容易.它没有,但我们可以给它一个.我将以下内容放入filter_plugins/enumerate.py:

If Ansible had an enumerate filter this would be pretty easy. It doesn't, but we can give it one. I put the following content into filter_plugins/enumerate.py:

#!/usr/bin/python


def filter_enumerate(v):
    return list(enumerate(v))


class FilterModule (object):
    def filters(self):
        return {
            'enumerate': filter_enumerate,
        }

对于列表[a, b, c],这将返回一个新列表[[0,a], [1,b], [2,c]].我们可以像这样在您的剧本中使用它:

For a list [a, b, c], this will return a new list [[0,a], [1,b], [2,c]]. We can use that in your playbook like this:

---
- hosts: localhost
  gather_facts: false
  vars:
    userlist:
      - alice
      - bob
      - mallory
    vms_per_user:
      - vm1
      - vm2
      - vm3
    vm_prefix: foo-

  tasks:
    - debug:
        msg:
          add_host:
            name: "{{ vm_prefix }}{{ item.0 }}-{{ item.1.1 }}"
            groups: vms
            vm_index: "{{ item.1.0 }}"
      loop: "{{ userlist | product(vms_per_user|enumerate) | list }}"

此调试任务的输出将类似于:

The output of this debug task will look something like:

ok: [localhost] => (item=[u'alice', [0, u'vm1']]) => {                                                                                                                                         
    "msg": {                                                                                                                                                                                   
        "add_host": {                                                                                                                                                                          
            "groups": "vms",                                                                                                                                                                   
            "name": "foo-alice-vm1",                                                                                                                                                           
            "vm_index": "0"                                                                                                                                                                    
        }                                                                                                                                                                                      
    }                                                                                                                                                                                          
}                                                                                                                                                                                              
ok: [localhost] => (item=[u'alice', [1, u'vm2']]) => {                                                                                                                                         
    "msg": {                                                                                                                                                                                   
        "add_host": {                                                                                                                                                                          
            "groups": "vms",                                                                                                                                                                   
            "name": "foo-alice-vm2",                                                                                                                                                           
            "vm_index": "1"                                                                                                                                                                    
        }                                                                                                                                                                                      
    }                                                                                                                                                                                          
}                                                                                                                                                                                              
ok: [localhost] => (item=[u'alice', [2, u'vm3']]) => {                                                                                                                                         
    "msg": {                                                                                                                                                                                   
        "add_host": {                                                                                                                                                                          
            "groups": "vms", 
            "name": "foo-alice-vm3", 
            "vm_index": "2"
        }
    }
}

这篇关于Ansible - 在列表产品上循环时枚举列表(嵌套循环)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆