如何避免Ansible uri模块中模板文件的变量误替换?
碰到这种Ansible把你自己的{{}}当成变量解析的情况,我有几个常用的解决办法,你可以根据自己的场景选择:
方法1:用Jinja2的raw块锁定不需要解析的内容
这是最灵活的方式,适合模板里既有需要Ansible替换的变量,又有你自己的{{}}占位符的场景。只需要把那些不想被解析的{{}}内容用{% raw %}和{% endraw %}包裹起来,Jinja2就会跳过这部分的变量解析,原样输出。
举个例子,假设你的knox-config.json内容是这样的:
{ "knox_custom_param": "{{ my_own_placeholder }}", "cluster_name": "{{ cluster_name }}" }
把需要保留的{{ my_own_placeholder }}用raw块包裹:
{ "knox_custom_param": {% raw %}"{{ my_own_placeholder }}"{% endraw %}, "cluster_name": "{{ cluster_name }}" }
这样Ansible只会正常解析{{ cluster_name }},而{{ my_own_placeholder }}会原封不动地出现在最终的请求body里。
方法2:转义双大括号
如果你不想用raw块,也可以直接把模板里的{{替换成{{ '{{' }},}}替换成{{ '}}' }}。Ansible渲染模板时,会把这两个表达式转换成{{和}}输出。
还是用上面的例子,修改后变成:
{ "knox_custom_param": "{{ '{{ my_own_placeholder }}' }}", "cluster_name": "{{ cluster_name }}" }
渲染后的结果会是:
{ "knox_custom_param": "{{ my_own_placeholder }}", "cluster_name": "你的集群名称" }
方法3:用lookup('file')替代lookup('template')(适合完全不需要模板渲染的场景)
如果你的knox-config.json里根本没有需要Ansible替换的变量,只是想原样读取文件内容,那可以把lookup('template')换成lookup('file')。这样Ansible会直接读取文件的原始内容,不会做任何模板解析操作:
- name: Set Config Knox - knox-config uri: url: "http://{{ ansible_fqdn }}:8080/api/v1/clusters/{{ cluster_name }}" method: PUT force_basic_auth: yes user: "{{ ambari_admin_user }}" password: "{{ ambari_admin_password }}" body: "{{ lookup('file','templates/knox/knox-config.json') }}" body_format: json
注意:这个方法只适合不需要渲染任何Ansible变量的情况,如果文件里还有其他需要替换的变量,就别用这个。
内容的提问来源于stack exchange,提问作者Safari
相关产品推荐
相关产品推荐

