31

I already know that if you have long conditionals with and between them you can use lists to split them on multiple lines.

Still, I am not aware of any solution for the case where you have OR between them.

Practical example from real life:

when: ansible_user_dir is not defined or ansible_python is not defined or ansible_processor_vcpus is not defined

This line is ugly and hard to read, and clearly would not fit a 79 column.

How can we rewrite it to make it easier to read?

sorin
  • 161,544
  • 178
  • 535
  • 806
  • Since you tagged this with `ansible-lint`, FYI there is no 80 character limit in the Ansible style standards implemented in `ansible-lint`. – Matthew Schuchard Nov 01 '18 at 12:32
  • 1
    The default limit is now 160 chars, but the need to write easy to read conditions is still valid. – sorin Aug 07 '19 at 05:14

2 Answers2

55

Use the YAML folding operator >

when: >
  ansible_user_dir is not defined or
  ansible_python is not defined or
  ansible_processor_vcpus is not defined

As the ansible documentation states:

Values can span multiple lines using | or >. Spanning multiple lines using a Literal Block Scalar | will include the newlines and any trailing spaces. Using a Folded Block Scalar > will fold newlines to spaces; it’s used to make what would otherwise be a very long line easier to read and edit. In either case the indentation will be ignored.

Additional info can be found here:

JGK
  • 3,710
  • 1
  • 21
  • 26
  • 1
    Does using `>-` instead of `>` make a meaningful difference here? – DaVince Dec 22 '21 at 09:05
  • `>-` strips newlines at the end of the string. You can play around with https://yaml-multiline.info/ – JGK Dec 22 '21 at 09:29
  • I know that; I just meant, does it have meaningful impact in this particular case? Since technically there would be a newline at the end of the when statement if the minus character isn't included. I'm thinking it doesn't matter to Ansible at all and would just unnecessarily confuse those who don't know about multiline statements, but I wanted to confirm it first. – DaVince Dec 22 '21 at 14:03
  • 1
    In this specific case, it doesn't matter, you're right. – JGK Dec 24 '21 at 10:41
  • 1
    Note that the spaces after `or` are _not_ necessary. – pt1 Mar 08 '23 at 09:58
  • 1
    @pt1 thank you for the hint, I removed all spaces at eol – JGK Mar 10 '23 at 21:32
0

While you should use yaml operators and syntax for majority of the Ansible code, you don't have to use yaml operators with when: conditional. Take a look at official docs. When conditional can be really flexible depends on your need. I think it works because when conditionals are already an expression and evaluated by Jinja2 directly, hence you don't use {{ }} in when condition.

Another great reference: https://stackoverflow.com/a/57600771/9720375

---
- name: Test multiline when condition
  hosts: all
  gather_facts: false
  strategy: linear
  tasks:
    - name: Should run
      debug:
        msg: "print this if works"
      when:
        - true
        - false or
          true

    - name: Should run
      debug:
        msg: "print this if works"
      when:
        - true
        - true or
          false

    - name: Should run
      debug:
        msg: "print this if works"
      when:
        - false or true

    - name: Should skip
      debug:
        msg: "print this if works"
      when:
        - false
        - false or true

    - name: Should run
      debug:
        msg: "print this if works"
      when:
        false or true

    - name: Should skip
      debug:
        msg: "print this if works"
      when:
        false or
        false

    - name: Should run
      debug:
        msg: "print this if works"
      when: (false or true) or (false and true)

    - name: Should run
      debug:
        msg: "print this if works"
      when: (false or false) or
            (true and true)
Shinebayar G
  • 4,624
  • 4
  • 18
  • 29