I recently had a need for with_sequence, but it doesn't seem possible to do
a zero count of actions.
Suppose i have a local action to create N things, perhaps vms or floating
ips. Some number M < N may already be present.
I'd like to do
hosts: localhost
vars:
expected_foo_count: 10
- name: Get the number of foos
shell: echo M
register: foo_count
- name: Create the missing number of foos
shell: make_new_foos
with_sequence: start=0 end="{{expected_foo_count -foo_count.stdout }}"
or with_sequence: count="{{expected_foo_count - foo_count.stdout}}"
This will work if M is strictly less than N, but if M=N (the idempotent
case) then ansible gives an error.
fatal: [localhost] => can't count backwards
I tried putting a "when" guard such as
when: "{{ expected_foo_count - foo_count.stdout > 0 }}"
But it appears "when" gets evaluated after the with_sequence conditional.
That in itself poses problems, since in branching code the register
variables may not be defined and you have to litter code with when: "{{
(register_var or '') | conditional }}".
The problem with the with_sequence is in the
lib/ansible/runner/lookup_plugins/sequence.py
def generate_sequence(self):
numbers = xrange(self.start, self.end+1, self.stride)
which means that contrary to conventional python such as
range(a,b) which gives a sequence starting at 'a' and ending at 'b-1', ie.
[a,b)
with_sequence: start=n end=m
runs over the sequence [n,m]. If n=m with_sequence still executes once, so
there is no possible way to have a with_sequence that runs zero times.
changing the generate_sequence code to
def generate_sequence(self):
numbers = xrange(self.start, self.end, self.stride)
Fixes the problem.
Is there a design reason behind not allowing for zero count sequences? If
so, how can a playbook including with_sequence be made idempotent?
kesten