首页 > 解决方案 > 如何评估 Ansible 模板?它们被“递归评估”是什么意思?

问题描述

在 Jinja2 中使用 raw/endraw 不会像您期望的那样工作,因为 Ansible 中的模板是递归评估的。

https://docs.ansible.com/ansible/latest/modules/template_module.html#notes
“最后更新于 2019 年 8 月 15 日”。适用于 Ansible 2.8。

“递归评估”的文档是什么意思?听起来很吓人。是特定于{% raw %}/的含义{% endraw %},还是有其他含义?

标签: ansibleescaping

解决方案


只要模板将评估,它们就会递归评估以允许变量嵌套。

因此,如果模板发生更改,它将继续运行。

我认为我们只需要记录这一点,而不是建议 raw/endraw。

--评论问题 #4638,“在模板中使用 {% raw %} 不会停止 jinja2 变量替换”

这似乎在某些时候发生了变化。如果我尝试在 Ansible 2.8 上的链接问题中运行复制器,原始/绘​​制按预期工作。

我在文档中将此报告为错误:#61233 模板操作不再递归评估变量。事实证明:

这里的情况好坏参半,[您的报告正在谈论]“模板”操作,而不是“ansible 中的模板”,这在处理方式上有所不同,但该操作似乎确实发生了行为变化。

我可以看到“ansible中的模板”在某种意义上被递归评估(Ansible 2.8.4):

$ ansible -m debug localhost -a msg='{{ a }}' -e 'a={{ b }}' -e 'b={{ a }}'

localhost | FAILED! => { "msg": "An unhandled exception occurred while templating '{{ b }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ a }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ b }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message:...An unhandled exception occurred while templating '{{ b }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: An unhandled exception occurred while templating '{{ a }}'. Error was a <class 'ansible.errors.AnsibleError'>, original message: recursive loop detected in template string: {{ a }}"

所以这看起来与命令式编程语言不同,比如 Python 或 Javascript。

我担心这是通过重新模板化输出字符串来实现的,直到它不包含{{. 这将是带内信令的可怕用途。

据我目前使用的版本所知,情况并非如此。即 Ansible 现在似乎正确地实现了惰性评估模型。

$ ansible -m debug localhost -a msg='{{ a }}' -e 'a={{ "{{ 1 }}" }}'

localhost | SUCCESS => {
    "msg": "{{ 1 }}"
}

推荐阅读