如何让 Ansible 解释变量内的变量? [英] How can I make Ansible interpret a variable inside a variable?
问题描述
每当我试图让 Ansible 解释一个嵌套变量时——所以,一个变量在另一个变量中——我无法得到我期望的结果.
Whenever I try to make Ansible interpret a nested variable — so, a variable inside another variable — I cannot get the result I expect.
给定变量:
key: bar
foo:
bar: baz
foo_bar: baz
我已经尝试了这三种方法,但没有多少运气来动态访问字典 foo
的键 bar
或键 foo_bar
,在构造时来自 key
的值:
I have tried those three approaches without much luck to dynamically access the key bar
of the dictionary foo
or the key foo_bar
, when constructed from the value of key
:
- ansible.builtin.debug:
msg: "{{ foo[{{ key }}] }}"
但是,我收到错误:
'模板字符串模板错误:预期标记'':'',得到''}''.字符串:{{ foo[{{ key }}] }}'
'template error while templating string: expected token '':'', got ''}''. String: {{ foo[{{ key }}] }}'
- ansible.builtin.debug:
msg: "{{ foo_{{ key }} }}"
但是,我遇到了类似的错误
But, I get a similar error
'模板字符串模板错误:预期标记''打印语句结束'',得到''{''.字符串:{{foo_{{key}}}}'
'template error while templating string: expected token ''end of print statement'', got ''{''. String: {{ foo_{{ key }} }}'
- ansible.builtin.debug:
msg: "{{ foo['{{ key }}'] }}"
在这里,我得到了错误
该任务包括一个带有未定义变量的选项.错误是:'dict object' 没有属性 '{{ key }}'
The task includes an option with an undefined variable. The error was: 'dict object' has no attribute '{{ key }}'
我期望得到 foo.bar
或 foo_bar
的值,所以 baz
.
实现这一目标的正确方法是什么?
I was expecting to get the value of foo.bar
or foo_bar
, so baz
.
What would be the correct approach to achieve this?
推荐答案
如 Ansible 的常见问题所述,小胡子不堆叠.
As advised in the Frequently Asked Questions of Ansible, moustache do not stack.
另一条规则是胡须不能堆叠".我们经常看到这个:
Another rule is ‘moustaches don’t stack’. We often see this:
{{ somevar_{{other_var}} }}
以上不符合您的预期,如果您需要使用动态变量,请酌情使用以下内容:
The above DOES NOT WORK as you expect, if you need to use a dynamic variable use the following as appropriate:
{{ hostvars[inventory_hostname]['somevar_' + other_var] }}
对于非主机变量",您可以使用 vars 查找 插件:
For ‘non host vars’ you can use the vars lookup plugin:
{{ lookup('vars', 'somevar_' + other_var) }}
因此,有两种情况适用:
So, there are two cases where this will apply:
尝试从变量访问字典的键时,您只需按原样使用该变量,请记住,当您在 表达式分隔符
{{ ... }}
,一个字符串将被解释为一个变量,如果不能用单引号或双引号括起来.
When trying to access a key of a dictionary from a variable, you would simply use the variable as is, remembering that, when you are inside the expression delimiters
{{ ... }}
, a string will be interpreted as a variable, if not enclosed inside simple or double quotes.
- ansible.builtin.debug:
msg: "{{ foo[key] }}"
vars:
key: bar
foo:
bar: baz
尝试从变量构造变量名称或字典键时,您必须使用 连接运算符,~
:
- ansible.builtin.debug:
msg: "{{ foo['foo_' ~ key] }}"
vars:
key: bar
foo:
foo_bar: baz
您可能还需要使用 vars
查找 或 vars
字典来访问动态变量:
You might also need to use the vars
lookup or the vars
dictionary to access a dynamic variable:
- ansible.builtin.debug:
msg: "{{ vars['foo_' ~ key] }}"
vars:
key: bar
foo_bar: baz
旁注:由于提出的原因,建议使用正确的连接运算符 ~
比 Ansible 文档中建议的数学运算符 +
在 Jinja 文档中:
Side note: it is more advisable to use the right concatenation operator, ~
than the math operator +
as advised in the Ansible documentation for the reason raised in Jinja documentation:
通常对象是数字,但如果两者都是字符串或列表,您可以通过这种方式连接它们.然而,这不是连接字符串的首选方式!对于字符串连接,请查看 ~
运算符.
来源:https://jinja.palletsprojects.com/en/2.11.x/templates/#math
这篇关于如何让 Ansible 解释变量内的变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!