【发布时间】:2020-06-12 02:11:30
【问题描述】:
总结
我有一个使用 Ansible 运行的 Jinja2 模板。
我希望我的模板加载另一个文件作为模板(即评估{{ var }}),然后我将对其进行过滤,然后然后将结果粘贴到顶级模板中。
我想我快到了,我只需要找到一个 Jinja2 过滤器,它接收一个字符串并将其解析为模板。
MWE
在此示例中,假设我要应用的过滤器只是将文件设为大写。 (显然这个案例非常简单,我可以在一个模板文件中完成。但我的实际用例更复杂。)
顶级模板main.yaml.j2:
---
something:
blah:
x: {{ y }}
{%- set names = [ 'John', 'Amy' ] %}
z: >
{{ lookup('file', './other-file.j2') | upper | indent(4*2) }}
other-file.j2:
{%- for name in names %}
Hello {{ name }}
{%- endfor %}
使用这个 Ansible playbook 运行它:
---
- hosts: localhost
connection: local
tasks:
- name: generate template
template:
src: "main.yaml.j2"
dest: "output.yaml.j2"
trim_blocks: False
register: templating
vars:
y: 5
期望的输出
---
something:
blah:
x: 5
z: >
HELLO JOHN
HELLO AMY
实际输出
---
something:
blah:
x: 5
z: >
{%- FOR NAME IN NAMES %}
HELLO {{ NAME }}
{%- ENDFOR %}
最佳猜测
我想我快到了。 我只需要一个将 Jinja2 模板应用于文本的过滤器。
即类似:
{{ lookup('file', './other-file.j2') | template | upper | indent(4*2) }}
(但template 不是真正的过滤器。也许还有另一个名字?)
我还尝试了什么
{{ include './other-file.j2' | upper | indent(4*2) }}
没用。
致命:[127.0.0.1]:失败! => {"changed": false, "msg": "AnsibleError: 模板化字符串时出现模板错误:预期令牌'打印语句结束',得到'字符串'。字符串:
---\nsomething:\n blah:\n x: {{ y }}\n {%- set names = [ 'John', 'Amy' ] %}\n z: >\n {{ include './other-file.j2' | upper | indent(4*2) }}"}
{% include './other-file.j2' | upper | indent(4*2) %}
“未找到模板:./OTHER-FILE.J2”
没用。
用例
对于上下文,我的用例是我有一个 Jinja2 模板生成 AWS CloudFormation 模板。 我试图在 YAML 中完成这一切,而不是 JSON。 (因为 YAML 可以有 cmets,而且你不必担心列表中的最后一项是否有尾随逗号,并且通常更容易读写和调试。) 一些 CloudFormation 资源需要将文字 JSON 粘贴到 YAML 文件中。 (例如CloudWatch Dashboard bodies)。 所以我想在 YAML 中有另一个文件,Jinja2 将其转换为 json,然后粘贴到我的整个 YAML 模板中。 我希望使用 for 循环生成此仪表板,并传入变量。 我想要一个单独的
【问题讨论】: