变量不会被正确过滤 [英] Variable won't be filtered correctly
问题描述
我做错了什么?我使用下面的任务来获取主机的所有定义的 log_dirs.这些信息存储在一个事实中,这是一个字典,这就像一个魅力.
- 名称:获取 all_log_dirs设置事实:all_log_dirs="{{ (all_log_dirs|default({})) | combine( { item.key:vars[item.key] } ) }}"with_dict: "{{ vars }}"当: item.key 是 search('^((?!splunk).)*_log_dir')
这里是适当的输出:
<块引用> "ansible_facts": {all_log_dirs":{"springboot_server_log_dir": "{{ server_deployment_dir }}/logs"}
但问题是,如果我现在想对 e 使用新的 dict.:
- 名称:如果不存在,则为 splunk 创建符号链接文件:源代码:{{ item.value }}"dest: "{{ splunk_log_dir }}/{{ item.key | regex_replace('_server_log_dir|_log_dir') | regex_replace('eap','jboss-eap') }}"状态:链接with_dict: "{{ all_log_dirs }}"
我只得到:
<块引用>failed: [...] (item={'value': u'{{ server_deployment_dir }}/logs', 'key': u'springboot_server_log_dir'}) =>{改变":假,调用":{模块参数":{"dest": "/somedir/springboot","path": "/somedir/springboot","src": "{{ server_deployment_dir }}/logs",状态":链接",}},"msg": "src 文件不存在,如果你真的想创建链接,请使用 \"force=yes\":/somedir/{{ server_deployment_dir }}/logs","path": "/somedir/springboot","src": "{{ server_deployment_dir }}/logs",状态":缺席"
}
为什么 {{ server_deployment_dir }} 没有被 Ansible 正确过滤?即使我将 src 更改为 dest 以及其他方法,它也不起作用,因为该变量没有被过滤.
{{ server_deployment_dir }} 的值当然是特定于主机的,类似于/opt/applicationXY/appDeployDir
不要使用 vars
对象.期间.
它是内部变量存储,用于在后台使用.
当 Ansible 模板引擎检测到 vars
访问时,它会停止进一步的模板链!
示例:
---- 主机:本地主机连接:本地收集事实:没有变量:myvar1:你好myvar2:世界myvar3:{{ myvar2 }}"任务:- 调试:msg: "{{ myvar1 }} {{ myvar3 }}"- 调试:msg: "{{ vars['myvar1'] }} {{ vars['myvar3'] }}"
结果:
TASK [调试] ***************************好的:[本地主机] =>{"msg": "你好世界"}任务 [调试] ****************************好的:[本地主机] =>{"msg": "你好 {{ myvar2 }}"}
更新:如果您完全需要通过 vars 对象访问变量,Ansible 2.5 中提供了 vars
查找;它像往常一样模板化值:
例如
- 调试:msg: "{{ lookup('vars','myvar1') }} {{ lookup('vars','myvar3') }}"
在我上一个示例的上下文中对 hello world
的结果.
what am I doing wrong? I use below task to get all defined log_dirs of a host. Those information are stored in a fact, which is a dict and this works like a charm.
- name: get all_log_dirs
set_fact:
all_log_dirs="{{ (all_log_dirs|default({})) | combine( { item.key:vars[item.key] } ) }}"
with_dict: "{{ vars }}"
when: item.key is search('^((?!splunk).)*_log_dir')
Here the appropriate output:
"ansible_facts": { "all_log_dirs": { "springboot_server_log_dir": "{{ server_deployment_dir }}/logs"}
But the problem is, if I now want to use the new dict for e. g.:
- name: create symlink for splunk if not present
file:
src: "{{ item.value }}"
dest: "{{ splunk_log_dir }}/{{ item.key | regex_replace('_server_log_dir|_log_dir') | regex_replace('eap','jboss-eap') }}"
state: link
with_dict: "{{ all_log_dirs }}"
I only get:
failed: [...] (item={'value': u'{{ server_deployment_dir }}/logs', 'key': u'springboot_server_log_dir'}) => { "changed": false, "invocation": { "module_args": { "dest": "/somedir/springboot", "path": "/somedir/springboot", "src": "{{ server_deployment_dir }}/logs", "state": "link", } }, "msg": "src file does not exist, use \"force=yes\" if you really want to create the link: /somedir/{{ server_deployment_dir }}/logs", "path": "/somedir/springboot", "src": "{{ server_deployment_dir }}/logs", "state": "absent"
}
Why isn't {{ server_deployment_dir }} filtered correctly by Ansible? Even I change src to dest and the way around, it won't work, because the variable isn't being filtered.
The value of {{ server_deployment_dir }} is of course host specific and is sth like /opt/applicationXY/appDeployDir
Don't use vars
object. Period.
It is internal variable storage intended for under-the-hood usage.
When Ansible template engine detects vars
access, it stops further templating chain!
Example:
---
- hosts: localhost
connection: local
gather_facts: no
vars:
myvar1: hello
myvar2: world
myvar3: "{{ myvar2 }}"
tasks:
- debug:
msg: "{{ myvar1 }} {{ myvar3 }}"
- debug:
msg: "{{ vars['myvar1'] }} {{ vars['myvar3'] }}"
Result:
TASK [debug] ***************************
ok: [localhost] => {
"msg": "hello world"
}
TASK [debug] ***************************
ok: [localhost] => {
"msg": "hello {{ myvar2 }}"
}
Update: if you utterly need to access variable trough vars object, there's vars
lookup available in Ansible 2.5; and it templates values as usual:
E.g.
- debug:
msg: "{{ lookup('vars','myvar1') }} {{ lookup('vars','myvar3') }}"
results to hello world
in the context of my previous example.
这篇关于变量不会被正确过滤的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!