如何让 Ansible 解释变量内的变量? [英] How can I make Ansible interpret a variable inside a variable?

查看:25
本文介绍了如何让 Ansible 解释变量内的变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每当我试图让 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.barfoo_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) }}
    

    来源:https://docs.ansible.com/ansible/latest/reference_appendices/faq.html#when-should-i-use-also-how-to-interpolate-variables-or-dynamic-variable-names

    因此,有两种情况适用:

    So, there are two cases where this will apply:

    1. 尝试从变量访问字典的键时,您只需按原样使用该变量,请记住,当您在 表达式分隔符{{ ... }},一个字符串将被解释为一个变量,如果不能用单引号或双引号括起来.

    1. 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屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆