Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ansible: How to test that a registered variable is not empty?

Tags:

yaml

ansible

How can I test that stderr is non empty::

- name: Check script
  shell: . {{ venv_name }}/bin/activate && myscritp.py
  args:
    chdir: "{{ home }}"
  sudo_user: "{{ user }}"
  register: test_myscript

- debug: msg='myscritp is Ok'
  when: not test_myscript.stderr

So if there is no error I could read::

  TASK: [deploy | debug msg='critp is Ok] *******
  ok: [vagrant] => {
      "msg": "myscritp is Ok"
  }

In case the stderr is not empty a FATAl error occurs.

like image 960
user3313834 Avatar asked Apr 28 '16 11:04

user3313834


People also ask

How is it possible to check if a variable is defined in Ansible?

As per latest Ansible Version 2.5, to check if a variable is defined and depending upon this if you want to run any task, use undefined keyword. Show activity on this post.

What does Set_fact do in Ansible?

This module allows setting new variables. Variables are set on a host-by-host basis just like facts discovered by the setup module. These variables will be available to subsequent plays during an ansible-playbook run.

How do I Undefine an Ansible variable?

No, there is no way to unset a variable (top level) in Ansible. The only thing you can do, is to create a dictionary and store the variable as a key in this dictionary. Clearing the "parent" dictionary will essentially make the dictionary. key is defined conditional expression work.

What is register command in Ansible?

Ansible register is a way to capture the output from task execution and store it in a variable. This is an important feature, as this output is different for each remote host, and the basis on that we can use conditions loops to do some other tasks. Also, each register value is valid throughout the playbook execution.


3 Answers

(ansible 2.9.6 ansible-lint 5.3.2)

See ansible-lint rules. The condition below results in error: 'empty-string-compare: Don't compare to empty string'

    when: test_myscript.stderr != ""

Correct syntax is

    when: test_myscript.stderr | length > 0

Quoting from source code

Use when: var|length > 0 rather than when: var != "" (or ' 'conversely when: var|length == 0 rather than when: var == "")


Notes

  1. Test empty bare variable e.g.
    - debug:
        msg: "Empty string '{{ var }}' evaluates to False"
      when: not var
      vars:
        var: ''

    - debug:
        msg: "Empty list {{ var }} evaluates to False"
      when: not var
      vars:
        var: []

give

  msg: Empty string '' evaluates to False
  msg: Empty list [] evaluates to False
  1. But, testing non-empty bare variable string depends on CONDITIONAL_BARE_VARS. Setting ANSIBLE_CONDITIONAL_BARE_VARS=false the condition works fine but setting ANSIBLE_CONDITIONAL_BARE_VARS=true the condition will fail
    - debug:
        msg: "String '{{ var }}' evaluates to True"
      when: var
      vars:
        var: 'abc'

gives

fatal: [localhost]: FAILED! => 
  msg: |-
    The conditional check 'var' failed. The error was: error while 
    evaluating conditional (var): 'abc' is undefined

Explicit cast to Boolean prevents the error but evaluates to False i.e. will be always skipped (unless var='True'). When the filter bool is used the options ANSIBLE_CONDITIONAL_BARE_VARS=true and ANSIBLE_CONDITIONAL_BARE_VARS=false have no effect

    - debug:
        msg: "String '{{ var }}' evaluates to True"
      when: var|bool
      vars:
        var: 'abc'

gives

skipping: [localhost]
  1. Quoting from Porting guide 2.8 Bare variables in conditionals
  - include_tasks: teardown.yml
    when: teardown

  - include_tasks: provision.yml
    when: not teardown

" based on a variable you define as a string (with quotation marks around it):"

  • In Ansible 2.7 and earlier, the two conditions above are evaluated as True and False respectively if teardown: 'true'

  • In Ansible 2.7 and earlier, both conditions were evaluated as False if teardown: 'false'

  • In Ansible 2.8 and later, you have the option of disabling conditional bare variables, so when: teardown always evaluates as True, and when: not teardown always evaluates as False when teardown is a non-empty string (including 'true' or 'false')

  1. Quoting from CONDITIONAL_BARE_VARS

Expect that this setting eventually will be deprecated after 2.12

like image 161
Vladimir Botka Avatar answered Oct 10 '22 11:10

Vladimir Botka


You can check for empty string (when stderr is empty)

- name: Check script
  shell: . {{ venv_name }}/bin/activate && myscritp.py
  args:
    chdir: "{{ home }}"
  sudo_user: "{{ user }}"
  register: test_myscript

- debug: msg='myscritp is Ok'
  when: test_myscript.stderr == ""

If you want to check for fail:

- debug: msg='myscritp has error: {{test_myscript.stderr}}'
  when: test_myscript.stderr != ""

Also look at this stackoverflow question

like image 44
Nasr Avatar answered Oct 10 '22 12:10

Nasr


when: myvar | default('', true) | trim != ''

I use | trim != '' to check if a variable has an empty value or not. I also always add the | default(..., true) check to catch when myvar is undefined too.

like image 24
Alex Avatar answered Oct 10 '22 10:10

Alex