0

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 
Nifle
  • 374
  • 1
  • 8
  • 22

2 Answers2

2

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"'
larsks
  • 43,623
  • 14
  • 121
  • 180
  • 1
    Wonderful. Works like a charm. Seems i really should read up on jinja, I never new either of those ways to format/concat strings – Nifle Feb 07 '23 at 20:07
1

Get rid of the extension .service. For example, put the below declarations into the group_vars

shell> cat group_vars/all/my_services.yml 
my_keys: "{{ ansible_facts.services.keys()|
             map('reverse')|
             map('split', '.', 1)|
             map('last')|
             map('reverse') }}"
my_services: "{{ dict(my_keys|zip(ansible_facts.services.values())) }}"

gives

  my_services:
    ModemManager:
      name: ModemManager.service
      source: systemd
      state: inactive
      status: disabled
    NetworkManager:
      name: NetworkManager.service
      source: systemd
      state: stopped
      status: masked
    ...

Given the variable

  component: ssh

Both getting the facts and testing the state are simpler. The code is cleaner.

    - debug:
        var: my_services[component]

gives

  my_services[component]:
    name: ssh.service
    source: systemd
    state: running
    status: enabled

and

    - debug:
        msg: "{{ component }} is running"
      when: my_services[component].state == 'running'

gives

  msg: ssh is running

Example of a complete playbook for testing

shell> cat pb.yml
- hosts: localhost

  vars:

    component: ssh

  tasks:

    - ansible.builtin.service_facts:
    - debug:
        var: my_services
      when: debug|d(false)|bool

    - debug:
        var: my_services[component]

    - debug:
        msg: "{{ component }} is running"
      when: my_services[component].state == 'running'
Vladimir Botka
  • 5,138
  • 8
  • 20