在我的剧本中,使用include_vars
模块包含了一个JSON文件。JSON文件的内容如下所示:
{
"Component1": {
"parameter1" : "value1",
"parameter2" : "value2"
},
"Component2": {
"parameter1" : "{{ NET_SEG_VLAN }}",
"parameter2": "value2"
}
}
在JSON文件包含在剧本中之后,我使用uri
模块发送一个http请求,如下所示:
- name: Configure Component2 variables using REST API
uri:
url: "http://0.0.0.0:5000/vse/api/v1.0/config/working/Component2/configvars/"
method: POST
return_content: yes
HEADER_x-auth-token: "{{ login_resp.json.token }}"
HEADER_Content-Type: "application/json"
body: "{{ Component2 }}"
body_format: json
可以看出,http请求的主体是用JSON数据Component2
发送的。然而,Jinja2试图替换JSON文件中的{{ NET_SEG_VLAN }}
,并抛出和undefined
错误。其目的不是使用Jinja2替换JSON文件中的任何内容,并按http请求中的原样发送正文。
如何防止Jinja2替换JSON文件中包含的变量?
即使使用{{'{{NET_SEG_VLAN}}'}}
,您也应该能够转义该变量,以告诉jinja不要在该块内模板化任何内容。
您应该能够用{% raw %}
和{% endraw %}
转义变量,以告诉Jinja不要在该块中使用模板。
!unsafe
来自文档https://docs.ansible.com/ansible/2.10/user_guide/playbooks_advanced_syntax.html#unsafe-或原始字符串:
在处理查找插件返回的值时,Ansible使用名为
unsafe
的数据类型来阻止模板化。将数据标记为不安全可以防止恶意用户滥用Jinja2模板在目标计算机上执行任意代码。Ansible实现确保从不模板化不安全的值。它比使用{% raw %} ... {% endraw %}
标签逃离Jinja2更全面。您可以在定义的变量中使用相同的
unsafe
数据类型,以防止模板错误和信息泄露。可以将vars_prompt提供的值标记为unsafe
。你也可以在剧本中使用unsafe。最常见的用例包括允许特殊字符(如{
或%
)的密码,以及看起来像模板但不应模板化的JSON参数。
我一直在使用它,就像这样:
# Load JSON content, as a raw string with !unsafe
- tags: ["always"]
set_fact:
dashboard_content: !unsafe "{{ lookup('file', './dash.json') | to_json }}"
# Build dictionnary via template
- tags: ["always"]
set_fact:
cc: "{{ lookup('template', './templates/cm_dashboard.yaml.j2') | from_yaml }}"
## cm_dashboard.yaml.j2 content:
hello: {{ cc_dashboard_content }}
# Now, "cc" is a dict variable, with "hello" field protected!