MMT
MMT

Reputation: 2111

Ansible evaluate variable before conditional statement

I'm trying to "print/display" only existing varaibles. The variable name is dynamic. The issue is that Ansible is not evaluating the the varibale name in the when: statement. Thus I can't get the when: (item.1 + '_wwn_' + item.0) is defined working correctly.

Play:

---
- hosts: 127.0.0.1

  vars:
    host_name: ['COM01ESX07', 'COM01ESX88']
    COM01ESX07_wwn_2: "This exist"

  tasks:
    - debug:
        var: "{{item.1}}_wwn_{{item.0}}"
      when: (item.1 + '_wwn_' + item.0) is defined
      with_nested:
        - ['1', '2']
        - "{{host_name}}"

Unfortunately this deplays all varaibles eventhough they are not defined

TASK [debug] *******************************************************************************************************************************************************************
ok: [127.0.0.1] => (item=[u'1', u'COM01ESX07']) => {
    "COM01ESX07_wwn_1": "VARIABLE IS NOT DEFINED!", 
    "item": [
        "1", 
        "COM01ESX07"
    ]
}
ok: [127.0.0.1] => (item=[u'1', u'COM01ESX88']) => {
    "COM01ESX88_wwn_1": "VARIABLE IS NOT DEFINED!", 
    "item": [
        "1", 
        "COM01ESX88"
    ]
}
ok: [127.0.0.1] => (item=[u'2', u'COM01ESX07']) => {
    "COM01ESX07_wwn_2": "This exist", 
    "item": [
        "2", 
        "COM01ESX07"
    ]
}
ok: [127.0.0.1] => (item=[u'2', u'COM01ESX88']) => {
    "COM01ESX88_wwn_2": "VARIABLE IS NOT DEFINED!", 
    "item": [
        "2", 
        "COM01ESX88"
    ]
}

However if I replace the when: with when: ({{item.1 + '_wwn_' + item.0}}) is defined

It will work, although I'll get the worning message:

TASK [debug] *******************************************************************************************************************************************************************
 [WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found: ({{item.1 + '_wwn_' + item.0}}) is defined

skipping: [127.0.0.1] => (item=[u'1', u'COM01ESX07']) 
skipping: [127.0.0.1] => (item=[u'1', u'COM01ESX88']) 
ok: [127.0.0.1] => (item=[u'2', u'COM01ESX07']) => {
    "COM01ESX07_wwn_2": "This exist", 
    "item": [
        "2", 
        "COM01ESX07"
    ]
}
skipping: [127.0.0.1] => (item=[u'2', u'COM01ESX88'])

The question: How can I avoid the worning message and still process only existing varaiables.

Upvotes: 0

Views: 1062

Answers (1)

larsks
larsks

Reputation: 312480

The problem is with your when condition. When you write...

when: (item.1 + '_wwn_' + item.0) is defined

...the part in parentheses is just string concatenation, and it all evaluates to a string. It's exactly like you were to write:

when: "something" is defined

That is, it will always be true. You're trying to use dynamic variable names, which is tricky. There is a FAQ on this topic on the ansible website. Basically, you will have to explicitly reference the hostvars toplevel variable (so you can use the string you've constructed as a dictionary key), so your task will look something like:

---
- hosts: localhost
  gather_facts: false
  vars:
    host_name: foo
  tasks:
    - set_fact:
        foo_wwn_1: wwn1

    - debug:
        var: "{{item.1}}_wwn_{{item.0}}"
      when: hostvars[inventory_hostname][item.1 + '_wwn_' + item.0] is defined
      with_nested:
        - ['1', '2']
        - "{{host_name}}"

Upvotes: 2

Related Questions