условные операторы не должны включать 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'