You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级至Ansible 2.19.0b4后_AnsibleLazyTemplateDict的update属性访问报错

问题解决:Ansible 2.19 中 '_AnsibleLazyTemplateDict' 的 'update' 方法访问报错

问题原因

Ansible Core 2.19 新增安全限制,禁止在 Jinja 模板中直接调用可变对象(如字典、列表)的修改方法(如 update()、append()),这类操作可能引发意外副作用或模板注入风险。你的角色代码中使用了 exclusion.update() 和 found.update() 这类方法,触发了该限制。

修复方案

重构 exclude_duplicates 角色中的 Jinja 模板,使用不可变操作替代可变方法:

  • 用 Jinja 的 namespace 维护状态(规避普通变量的不可变性限制)
  • 用 combine 过滤器合并字典(替代 update())
  • 用列表拼接(+)替代 append()

修正后的角色代码

---
- name: Find hosts to exclude
  local_action:
    module: set_fact
    exclusion_results: |
      {%- set ns = namespace(exclusion={}, found={}) -%}
      {%- for tmp_item in hostvars | dict2items | rejectattr('value.ansible_machine_id', 'undefined') | map(attribute='value') -%}
      {%- set item = {'ansible_machine_id': tmp_item.ansible_machine_id, 'inventory_hostname': tmp_item.inventory_hostname} -%}
      {%- if item.ansible_machine_id in ns.found -%}
          {%- if item.inventory_hostname not in ns.exclusion -%}
              {%- set ns.exclusion = ns.exclusion | combine({item.inventory_hostname: {}}) -%}
          {%- endif -%}
          {%- set ns.exclusion = ns.exclusion | combine({
              item.inventory_hostname: ns.exclusion[item.inventory_hostname] | combine({
                  item.ansible_machine_id: ns.found[item.ansible_machine_id]
              })
          }) -%}
          {%- set ns.found = ns.found | combine({
              item.ansible_machine_id: ns.found[item.ansible_machine_id] + [item]
          }) -%}
      {%- else -%}
          {%- set ns.found = ns.found | combine({item.ansible_machine_id: [item]}) -%}
      {%- endif -%}
      {%- endfor -%}
      {{ {'exclusion': ns.exclusion, 'found': ns.found} }}
  run_once: true

- name: print final
  run_once: true
  debug:
    var: exclusion_results

- block:
    - name: "end_host"
      debug:
        msg: |
          host {{ inventory_hostname }}, duplicate of {{ exclusion_results.exclusion[inventory_hostname][ansible_machine_id] | map(attribute='inventory_hostname') }}

    - ansible.builtin.meta: end_host
  when: inventory_hostname in exclusion_results.exclusion

说明

  • 修复完全保留原逻辑:识别重复 ansible_machine_id 的主机,并将重复主机加入排除列表
  • 所有操作均为不可变(创建新对象而非修改原对象),符合 Ansible 2.19 的安全要求
  • 其余 Playbook 代码无需修改

内容的提问来源于stack exchange,提问作者user000001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:35:03