条件语句不应该包含带有字典列表的 jinja2

条件语句不应该包含带有字典列表的 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 

答案1

您永远不会嵌套 Jinja{{...}}标记。如果您在模板上下文中(隐式地,在语句中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"'

答案2

删除扩展.service。例如,将以下声明放入组变量

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'

相关内容