Ansible Jinja2 – Conditional Statements Should Not Include Dictionary List

ansiblejinja2

How do I get rid of this warning?
The task works as expected but I would like to do it correctly

I have tried to fish out the value for ansible_facts.services["{{ component }}.service"].state and save it in a variable without any success.

---

- hosts: localhost
  become: no
  gather_facts: true

  vars:
    component: firewalld

  tasks:

  - name: Populate service facts
    ansible.builtin.service_facts:

  - name: "servicestatus"
    debug:
      msg: "{{ component }} is running, do stuff"
    when: 'ansible_facts.services["{{ component }}.service"].state == "running"'

  - name: "wokka"
    debug:
      var: ansible_facts.services["{{component}}.service"].state
$ ansible-playbook example.yml

PLAY [localhost] **************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************
ok: [localhost]

TASK [Populate service facts] *************************************************************************************
ok: [localhost]

TASK [servicestatus] **********************************************************************************************
[WARNING]: conditional statements should not include jinja2 templating delimiters such as {{ }} or {% %}. Found:
ansible_facts.services["{{ component }}.service"].state == "running"
ok: [localhost] => {
    "msg": "firewalld is running, do stuff"
}

TASK [wokka] ******************************************************************************************************
ok: [localhost] => {
    "ansible_facts.services[\"firewalld.service\"].state": "running"
}

PLAY RECAP ********************************************************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

Best Answer

You never nest Jinja {{...}} markers. If you're inside a template context (which you are, implicitly, in a when statement), you just refer to variables by name. So instead of:

  - name: "servicestatus"
    debug:
      msg: "{{ component }} is running, do stuff"
    when: 'ansible_facts.services["{{ component }}.service"].state == "running"'

  - name: "wokka"
    debug:
      var: ansible_facts.services["{{component}}.service"].state

You want:

  - name: "servicestatus"
    debug:
      msg: "{{ component }} is running, do stuff"
    when: 'ansible_facts.services[component ~ ".service"].state == "running"'

  - name: "wokka"
    debug:
      var: ansible_facts.services[component ~ ".service"].state

Here we're using the ~ string concatenation operator. You could accomplish the same thing with string formatting syntax, like this:

  - name: "servicestatus"
    debug:
      msg: "{{ component }} is running, do stuff"
    when: 'ansible_facts.services["%s.service" % (component)].state == "running"'