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

Ansible中如何延迟Jinja2模板字符串的循环内求值?

解决方案

方法一:配置文件存储无花括号的表达式(推荐)

先修改你的配置变量文件,移除eval字段的{{}},只保留纯表达式内容:

checks:
  - name: "x"
    setting: "y"
    eval: "'OK' if var == 'x' else 'NOK'"

接着修改do.yml的Save stuff任务,使用template过滤器在var注册后动态渲染表达式:

---
- debug:
    var: item

- name: Do stuff
  shell: echo "x"  # 示例命令,替换为你的实际操作
  register: var

- name: Save stuff
  set_fact:
    result: "{{ result | d([]) + [ res ] }}"
  vars:
    res:
      name: "{{ item.name }}"
      setting: "{{ item.setting }}"
      result: "{{ item.eval | template }}"

方法二:保留配置文件中的花括号(转义避免提前模板化)

如果必须保留配置里的{{}},需要先转义花括号,防止Ansible在解析checks变量时提前模板化:

checks:
  - name: "x"
    setting: "y"
    eval: "{% raw %}{{ 'OK' if var == 'x' else 'NOK' }}{% endraw %}"

或者用字符串拼接转义:

checks:
  - name: "x"
    setting: "y"
    eval: "{{ '{{' }} 'OK' if var == 'x' else 'NOK' {{ '}}' }}"

之后同样在do.yml的Save stuff任务中使用template过滤器延迟求值,代码和方法一一致。

问题根源

你之前的写法中,main.yml里的loop: "{{ checks }}"会触发Ansible提前对整个checks变量做模板渲染——此时var还未被注册,eval字段会被直接解析为NOK,后续任务引用的只是这个提前计算好的静态值,而非基于最新上下文的动态结果。

通过将表达式以纯字符串存储,再在var注册后用template过滤器动态渲染,就能实现延迟求值的效果。

内容的提问来源于stack exchange,提问作者Michal Zaorálek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 18:29:59