Mike Vella
Mike Vella

Reputation: 10585

Add an item to a list dependent on a conditional in ansible

I would like to add an item to a list in ansible dependent on some condition being met.

This doesn't work:

  some_dictionary:
    app:
       - something
       - something else
       - something conditional # only want this item when some_condition == True
         when: some_condition

I am not sure of the correct way to do this. Can I create a new task to add to the app value in the some_dictionary somehow?

Upvotes: 13

Views: 17538

Answers (4)

You can filter out all falsey values with select(), but remember to apply the list() filter afterwards. This seems an easier and more readable approach for me:

- name: Test
  hosts: localhost
  gather_facts: no
  vars:
      mylist:
        - "{{ (true)  | ternary('a','') }}"
        - "{{ (false) | ternary('b','') }}"
        - "{{ (true)  | ternary('c','') }}"
 
  tasks:
  - debug:
      var: mylist|select|list

Result:

TASK [debug] *****************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "mylist|select()|list": [
        "a", 
        "c"
    ]
}

Replace (true) and (false) with whatever test you want.

Upvotes: 11

Halberom
Halberom

Reputation: 471

Is there a reason you have to do everything in one go?

This is pretty easy if you specify the additional item(s) to add in separate vars, as you can just do list1 + list2.

---
- hosts: localhost
  gather_facts: False
  connection: local
  vars:
    mylist:
      - one
      - two
    mycondition: False
    myconditionalitem: foo
  tasks:
    - debug:
        msg: "{{ mylist + [myconditionalitem] if mycondition else mylist }}"

Upvotes: 5

mejo
mejo

Reputation: 1

Based on Konstantin's solution I developed the following:

- hosts: localhost
  gather_facts: no
  vars:
    a: "{{ True if var1|d(True) else False }}"
    b: "{{ True if var2|d(False) else False }}"
    n: "{{ True if var2|d(True) else False }}"
    some_list: "{{ '[' +
                     a|ternary('\"item1\",',' ') +
                     b|ternary('\"item2\",',' ') +
                     n|ternary('\"itemN\",',' ') + ']' }}"
  tasks:
    - debug: var=some_list

This will create a list with items "item1" till "itemN", but each item is only appended if the corresponding flag expands to 'True'.

Hope, this helps.

Upvotes: 0

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68329

I'd try to avoid this, but if conditional list is absolutely necessary, you can use this trick:

---
- hosts: localhost
  gather_facts: no
  vars:
    a: 1
    b: 1
    c: 2
    some_dictionary:
      app: "{{ '[\"something\", \"something else\"' + (a + b == c) | ternary(', \"something conditional\"',' ') + ']' }}"
  tasks:
    - debug: var=some_dictionary.app

It will form an array-like string (["item1","item2","item3"]) and ansible variable templator will convert it into list before assigning to app.

Upvotes: 4

Related Questions