Unable to use Parentheses for Jinja2 functions in Conditionals

Hello,

I’m having problems using a Jinja2 function in an Ansible conditional and was hoping someone could please help me find a way around it.

As far as I can tell I must use both parentheses and single quotes in the Jinja2 function I’m using but these mean that I cannot avoid Ansible reporting template errors.

  • I want a role to run at all times EXCEPT between 01:45 to 02:20 UTC.
  • I cannot ensure that the OS uses UTC timezone, so found the Jinja2 now() function is the best way to determine this.

I’ve tried a few different varients of the conditionals below but this is the easiest format to read:

- name: workstation role
  hosts: localhost
  connection: local
  become: true
  tasks:
    - name: WORKSTATION_ROLE
      include_role:
        name: workstation
      # Skip role execution during daily patch window to avoid conflicts with apt lock.  Do not run between 01:45 and 02:20
      when:
        - not ( now('utc').hour == 01 and now('utc').minute >= 45 )
        - not ( now('utc').hour == 02 and now('utc').minute < 20 )

Ansible returns the error:

The error was: template error while templating string: expected token ')', got 'integer'. String: {% if not ( now('utc').hour == 01 and now('utc').minute >= 45 ) %} True {% else %} False {% endif %}

but I need to use those parentheses for the now() function and also cannot use single quotes to escape them as they are required for the ‘utc’ argument.

EDIT: I’ve also tried negating the whole conditional, but then need to use parentheses because I need to use a logical OR instead of a logical AND.

Any tips for what I should try please?

Thank you in advance!

PS: I could not find any complex examples of the use of parentheses in official Ansible documentation and nothing like the problem I have with needing to use them inside the conditional “template”.

If anyone tries to test this, note that the conditional only fails when the hour is either 01 or 02. Please change those hours to suit whenever you are testing.

Ansible-lint doesn’t pick up this problem either.

TIA!

The issue has nothing to do with functions or parentheses, it’s your erroneous leading zeros.

        - not ( now('utc').hour == 1 and now('utc').minute >= 45 )
        - not ( now('utc').hour == 2 and now('utc').minute < 20 )

01 is not a valid integer literal, so it confuses the parsing and you get an error related to the enclosing context.

- hosts: localhost
  tasks:
    - debug:
      when:
        - '02'
TASK [debug] *******************************************************************
fatal: [localhost]: FAILED! => 
    msg: |-
        The conditional check '02' failed. The error was: template error while templating string: expected token 'end of statement block', got 'integer'. String: {% if 02 %} True {% else %} False {% endif %}. expected token 'end of statement block', got 'integer'
3 Likes

Thank you very much! That’s it!

I wasn’t sure of the format of now('utc').hour was and hadn’t thought about that.