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 }}"
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 - 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
Thank you!
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,
}
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"
}
}
}
Etc.