условные операторы не должны включать jinja2 со списком словарей

Как мне избавиться от этого предупреждения?
Задача работает так, как ожидалось, но мне хотелось бы сделать ее правильно.

Я попытался выловить значение дляansible_facts.services["{{ component }}.service"].stateи безуспешно сохраните его в переменной.

      ---

- 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 

2 ответа

Ты никогда не гнездишь Джинджу{{...}}маркеры. Если вы находитесь внутри контекста шаблона (а вы, неявно, находитесь вwhenоператор), вы просто ссылаетесь на переменные по имени. Итак, вместо:

        - 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

Вы хотите:

        - 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

Здесь мы используем~оператор конкатенации строк. Вы можете сделать то же самое с помощью синтаксиса форматирования строк, например:

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

Избавьтесь от расширения .service. Например, поместите приведенные ниже объявления в файл 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())) }}"

дает

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

Учитывая переменную

        component: ssh

И получить факты, и проверить состояние проще. Код чище.

          - debug:
        var: my_services[component]

дает

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

и

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

дает

        msg: ssh is running

Пример полного сценария для тестирования

       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'
Другие вопросы по тегам