Q:

Generate random number while the generated number is on a list - ansible

I'm trying to generate random numbers in ansible while the generated number, exists in a list of numbers.
Let's suppose that my list have this values.
list = [1, 3, 5, 8, 9, 10]

I'm using the module set_fact like this.
- set_fact:
    value: "{{ (1,10) | random }}"
  until: value not in list

The value generated using the random rule always generate the number 1 or 10, I've used the module debug like the code below and it always generate different numbers.
- debug:
    msg: "{{ (1,10) | random }}"

My problem here is, how can I generate random number in a certain interval, like the one above (1,10) and how can I keep generating random numbers while the generated number exists in the list, when the generated number isn't in the list, i want to stop the loop and use this number for something.

A:

This is very tricky and actually i cant say i have a clean solution for you. First things first, to get a random number from 1 to 10 you have to use:
msg: "{{ 10 | random(start=1 }}"

Problem is, that this task doesn't work as we would expected it, i guess the until clause works in mysterious ways (will explain later why):
- set_fact:
    value: "{{ 10 | random(start=1) }}"
  until: value not in list

Running it a few times, you will realize that the until loop is "bypassed" and sometimes you get values that are in the exclusion list list variable.
You can try with include_tasks to extend the loop to 2 tasks (one to get the random integer, then to assign to your value variable if not in the list, but the until clause of the include_tasks task will still not work.
One workaround solution i found to work is by using a shell command to generate a random number, have that value as the commands "exit code" (as just stdout will not work!!) and if exit code not in the list list, then assign it to the value var. 
The task's code:
---
- hosts: localhost
  connection: local
  gather_facts: false
  vars:
    my_list: [1, 3, 5, 7, 9, 10]  

  tasks:
    - name: run shell to get random number
      shell: exit `shuf -i 1-10 -n 1` 
      register: shell_command
      failed_when: shell_command.rc > 100
      until: shell_command.rc not in my_list
      retries: 1000
      delay: 1

    - name: print results
      debug:
        var: shell_command.rc

sample run:
[root@optima-ansible ILIAS]# ansible-playbook testt.yml 

PLAY [localhost] ****************************************************************************************************************************************************************************************************

TASK [run shell to get random number] *******************************************************************************************************************************************************************************
FAILED - RETRYING: run shell to get random number (1000 retries left).
FAILED - RETRYING: run shell to get random number (999 retries left).
changed: [localhost]

TASK [print results] ************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "shell_command.rc": "8"
}

PLAY RECAP **********************************************************************************************************************************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0   

[root@optima-ansible ILIAS]# 

As stated before, if you use echo instead of exit in the shell command, and shell_command.stdout instead of shell_command.rc, the until will not work as expected.
Would be glad to see a pure ansible implementation to this question (although i got the feeling that it wont be as straightforward as this).
hope these help

