70

有时我需要测试一些我在 ansible 角色中使用的 jinja2 模板。这样做的最简单方法是什么?

例如,我有一个模板(test.j2):

{% if users is defined and users %}
{% for user in users %}{{ user }}
{% endfor %}
{% endif %}

和 vars(在 group_vars/all 中):

---
users:
  - Mike
  - Smith
  - Klara
  - Alex
4

5 回答 5

100

目前存在 4 种不同的变体:

1_Online(使用https://cryptic-cliffs-32040.herokuapp.com/
基于jinja2-live-parser代码。

例子

2_Interactive(使用python和库jinja2,PyYaml)

import yaml
from jinja2 import Template
>>> template = Template("""
... {% if users is defined and users %}
... {% for user in users %}{{ user }}
... {% endfor %}
... {% endif %}
... """)
>>> values = yaml.load("""
... ---
... users:
...   - Mike
...   - Smith
...   - Klara
...   - Alex
... """)
>>> print "{}".format(template.render(values))


Mike
Smith
Klara
Alex

3_Ansible(使用--check)
创建测试剧本jinja2test.yml:

---
- hosts: 127.0.0.1
  tasks:
  - name: Test jinja2template
    template: src=test.j2 dest=test.conf

并运行它:

ansible-playbook jinja2test.yml --check --diff --connection=local

样本输出:

PLAY [127.0.0.1] **************************************************************

GATHERING FACTS ***************************************************************

ok: [127.0.0.1]

TASK: [Test jinja2template] ***************************************************
--- before: test.conf
+++ after: /Users/user/ansible/test.j2
@@ -0,0 +1,4 @@
+Mike
+Smith
+Klara
+Alex

changed: [127.0.0.1]

PLAY RECAP ********************************************************************
127.0.0.1                  : ok=2    changed=1    unreachable=0    failed=0

4_Ansible(使用 -m 模板)感谢@artburkart

创建一个名为 test.txt.j2 的文件

{% if users is defined and users %}
{% for user in users %}
{{ user }}
{% endfor %}
{% endif %}

像这样调用ansible:

ansible all -i "localhost," -c local -m template -a "src=test.txt.j2 dest=./test.txt" --extra-vars='{"users": ["Mike", "Smith", "Klara", "Alex"]}'

它将输出一个test.txt在当前目录中调用的文件,该文件将包含评估test.txt.j2模板的输出。

我知道这并不直接使用 vars 文件,但我认为这是在不使用任何外部依赖项的情况下测试模板的最简单方法。另外,我相信 jinja2 库提供的和 ansible 提供的有一些差异,所以直接使用 ansible 可以规避任何差异。当提供的 JSON--extra-vars满足您的需求时,您可以将其转换为 YAML 并继续使用。

于 2016-02-15T11:10:01.637 回答
47

如果您有一个名为 jinja2 的模板test.j2和一个位于 的 vars 文件group_vars/all.yml,那么您可以使用以下命令测试该模板:

ansible all -i localhost, -c local -m template -a "src=test.j2 dest=./test.txt" --extra-vars=@group_vars/all.yml

它将输出一个test.txt在当前目录中调用的文件,该文件将包含评估test.j2模板的输出。

我认为这是在不使用任何外部依赖项的情况下测试模板的最简单方法。此外,jinja2 库提供的和 ansible 提供的有所不同,因此直接使用 ansible 可以规避任何差异。也可以使用 JSON 测试临时变量,而无需制作额外的 vars 文件:

ansible all -i "localhost," -c local -m template -a "src=test.j2 dest=./test.txt" --extra-vars='{"users": ["Mike", "Smith", "Klara", "Alex"]}'
于 2017-01-16T18:35:47.910 回答
10

您可以使用调试模块

tasks: 
- name: show templating results
  debug:
   msg: "{{ lookup('template', 'template-test.j2') }}"
于 2020-01-27T13:42:34.180 回答
4

免责声明 - 我是本文的作者,但我将 JinjaFx ( https://github.com/cmason3/jinjafx ) 放在一起。

这是一个基于 Python 的工具,它允许您将带有 YAML 文件的 Jinja2 模板传递给变量。我最初编写它是为了它可以传递基于 CSV 的数据来为我们的部署生成 group_vars 和 host_vars,但它也允许轻松测试 Jinja2 模板 - https://jinjafx.io上有一个在线版本

于 2020-05-21T10:51:03.410 回答
1

我需要验证我定义的模板是否为创建它的服务器提供了正确的结果。(模板包括主机名作为变量和其他每个主机定义的变量。)

以上两种方法都不适合我。我的解决方案是添加

  check_mode: yes
  diff: yes

对于执行模板命令的任务,这让我知道了生成的文件和服务器上实际文件之间的差异,而无需更改远程文件。对我来说,它实际上比查看整个生成的文件效果更好,因为无论如何更改都是有趣的部分。它需要在远程机器上登录,所以用例有限。完整命令示例:

    - 名称:diff server.properties
      check_mode:是的
      差异:是的
      ansible.builtin.template:
        src:“src.properties”
        目标:“/opt/kafka/config/server.properties”
于 2021-06-22T07:34:39.503 回答