# with\_sequence is incompatible with idempotency

**URL:** <https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120>\
**Category:** Ansible Project\
**Created:** [April 30, 2014, 1:34pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120 "2014-04-30T13:34:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Kesten\_Broughton2](https://avatars.discourse-cdn.com/v4/letter/k/ecc23a/32.png) [@Kesten\_Broughton2](https://forum.ansible.com/u/Kesten_Broughton2)\
**Post date:** [April 30, 2014, 1:34pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/1 "2014-04-30T13:34:07Z")

</div>

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:  
&nbsp;&nbsp;&nbsp;expected\_foo\_count: 10

- name: Get the number of foos  
&nbsp;&nbsp;&nbsp;shell: echo M  
&nbsp;&nbsp;&nbsp;register: foo\_count

- name: Create the missing number of foos  
&nbsp;&nbsp;&nbsp;shell: make\_new\_foos  
&nbsp;&nbsp;&nbsp;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

&nbsp;&nbsp;&nbsp;&nbsp;def generate\_sequence(self):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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

&nbsp;&nbsp;&nbsp;&nbsp;def generate\_sequence(self):  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [April 30, 2014, 8:03pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/2 "2014-04-30T20:03:56Z")

</div>

You are throwing two words together that have nothing to do with each other.

with\_sequence is a loop.

Idempotency is a mathematical statement that says “F(X) = F(F(X))” for how many times X is applied.

“This will work if M is strictly less than N, but if M=N (the idempotent case) then ansible gives an error.”

What you have here is Ansible giving an error. It has nothing to do with idempotency.

It may imply “with sequence can’t traverse a zero length list”, which more accurately describes the problem.

So, the best thing to do here is to share what the error is and we can go from there.

---

<div class="post-metadata">

**Author:** ![kesten\_broughton1](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kesten\_broughton1](https://forum.ansible.com/u/kesten_broughton1)\
**Post date:** [April 30, 2014, 9:51pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/3 "2014-04-30T21:51:12Z")

</div>

The error is  
fatal: [localhost] =\> can’t count backwards

This occurs whenever count=0 or start=M end=M

If with\_sequence is used for the purpose of bringing a system to a state = HAS N of something  
then there should be a way of running the playbook twice and not having anything new created.  
That’s what i meant by idempotent.

“with sequence can’t traverse a zero length list” accurately describes my concern

kesten

---

<div class="post-metadata">

**Author:** ![PhilEv](https://avatars.discourse-cdn.com/v4/letter/p/ee59a6/32.png) [@PhilEv](https://forum.ansible.com/u/PhilEv)\
**Post date:** [May 1, 2014, 7:32am UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/4 "2014-05-01T07:32:23Z")

</div>

In similar case A workaround I used is to add 1 to your sequence count

see [https://mail.google.com/mail/#search/label%3Aansible+with\_sequence/1435e13b34e3a0e1](https://mail.google.com/mail/#search/label%3Aansible+with_sequence/1435e13b34e3a0e1)

Phil

---

<div class="post-metadata">

**Author:** ![kesten\_broughton1](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kesten\_broughton1](https://forum.ansible.com/u/kesten_broughton1)\
**Post date:** [May 1, 2014, 1:34pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/5 "2014-05-01T13:34:41Z")

</div>

Phil, the link doesn’t work for me.

---

<div class="post-metadata">

**Author:** ![PhilEv](https://avatars.discourse-cdn.com/v4/letter/p/ee59a6/32.png) [@PhilEv](https://forum.ansible.com/u/PhilEv)\
**Post date:** [May 1, 2014, 7:17pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/6 "2014-05-01T19:17:05Z")

</div>

The link references a previous exchange similar to yours

The specific case was about using the lineinfile module and with\_sequence

to add a parameter to all the kernel liles in grub.conf

here is a copy of what I wrote:

"

tasks 1: count the number of lines to replace (via shell module using and grep -E | wc -l )  
using register to remember the linecounted

task 2: using lineinfile and with\_sequence: linecounted

one caveat is that with sequence does not accept a 0 count ( a potential future improvement ?)

so just add 1 to the count (you do not care about doing it one more time)

then you can run those 2 tasks multiples times

works for me on grub.conf  
"

Phil

---

<div class="post-metadata">

**Author:** ![kesten\_broughton1](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kesten\_broughton1](https://forum.ansible.com/u/kesten_broughton1)\
**Post date:** [May 1, 2014, 7:44pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/7 "2014-05-01T19:44:55Z")

</div>

ah, thanks phillippe.

I think in my case this won’t work since i DO care about doing it one more time.  
The thing i’m doing is creating vms. But i don’t want to create 1 more if i already have my desired N.

k

---

<div class="post-metadata">

**Author:** ![PhilEv](https://avatars.discourse-cdn.com/v4/letter/p/ee59a6/32.png) [@PhilEv](https://forum.ansible.com/u/PhilEv)\
**Post date:** [May 1, 2014, 7:52pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/8 "2014-05-01T19:52:23Z")

</div>

sure !  
So being able to traverse a zero length list would fix yours issue

and avoid the need for my workaround

Phil

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [May 1, 2014, 9:32pm UTC](https://forum.ansible.com/t/with-sequence-is-incompatible-with-idempotency/15120/9 "2014-05-01T21:32:17Z")

</div>

So it seems easiest to just make it so it can create zero length lists.

Please make sure there’s a github ticket and this can be dealt with.

Tickets go here: [github.com/ansible/ansible](http://github.com/ansible/ansible)

(Fix pull requests are even better)

Thanks!
