在 Ansible/Jinja2 中设置 var 的 case 语句
Posted
技术标签:
【中文标题】在 Ansible/Jinja2 中设置 var 的 case 语句【英文标题】:Case statement for setting var in Ansible/Jinja2 【发布时间】:2015-08-18 15:56:23 【问题描述】:我将 Ansible 与 Jinja2 模板一起使用,这是我无法在 Ansible 的文档中找到解决方案或在谷歌上搜索 Jinja2 示例的场景。这是我想在 Ansible 中实现的逻辑:
if existing_ansible_var == "string1"
new_ansible_var = "a"
else if existing_ansible_var == "string2"
new_ansible_var = "b"
<...>
else
new_ansible_var = ""
我可以通过结合几种技术来做到这一点,这里的变量赋值:Set variable in jinja,这里的条件比较:http://jinja.pocoo.org/docs/dev/templates/#if-expression,以及这里的默认过滤器:https://docs.ansible.com/playbooks_filters.html#defaulting-undefined-variables,
...但我觉得这有点矫枉过正。有没有更简单的方法来做到这一点?
【问题讨论】:
你想达到什么目的? 我正在尝试根据几个条件设置new_ansible_var
,以便我可以在.j2 模板中使用new_ansible_var
我知道了,但你为什么要这个?如果您说明您的实际问题是什么,我们或许可以帮助您以更好的方式解决问题。
请在下面查看我的更新答案。除了简单地写出值之外,我还添加了一个定义 var 的示例。
@AntonisChristofides - 在我的.j2
文件中,我有一行我想看起来像这样:tags: perm_tags optional_tags
。当且仅当 machine_type
匹配许多不同字符串之一时,optional_tags
应该有一个值。字符串比较集未来可能会增长,或者除了machine_type
之外可能还有其他变量。理想情况下,我的 .j2 标记会更加通用,因此 tags: my_tags
和 my_tags
的行将在其他地方(即在 vars 文件中?)定义为 perm_tags
与 optional_tags
连接
【参考方案1】:
您不需要设置 var,因为我猜您稍后会尝试为某些条件设置 var。 只是在那里创造条件
- name: Later task
shell: "command is here"
when: existing_ansible_var == "string1"
并获得利润
【讨论】:
【参考方案2】:这样的东西会起作用,但它很难看。正如@podarok 在他的回答中提到的那样,这可能是不必要的,具体取决于您正在尝试做什么:
- name: set default
set_fact: new_ansible_var= ""
- name: set to 'a'
set_fact: new_ansible_var= "a"
when: " existing_ansible_var == string1"
- name: set to 'b'
set_fact: new_ansible_var= "b"
when: " existing_ansible_var == string2"
等等
【讨论】:
这些示例的第 2 行应如下所示:set_fact: new_ansible_var= "a"
才能运行它。我进行了更改,现在运行播放时出现以下错误,这非常无用:TASK: [sbc | set to 'a'] ***************************************************** fatal: [my-machine] => error while evaluating conditional: existing_ansible_var == string1 FATAL: all hosts have already failed -- aborting
我还必须使第三行看起来像:when: " existing_ansible_var == string1"
【参考方案3】:
如果您只想根据existing_ansible_var
的值在模板中输出一个值,您只需使用字典并使用existing_ansible_var
提供它。
"string1": "a", "string2": "b"[existing_ansible_var] | default("")
你可以用同样的方法定义一个新变量:
% set new_ansible_var = "string1": "a", "string2": "b"[existing_ansible_var] | default("") -%
如果existing_ansible_var
可能不一定被定义,您需要使用您的字典中不存在的default()
来捕获它:
"string1": "a", "string2": "b"[existing_ansible_var | default("this key does not exist in the dict")] | default("")
您也可以在剧本中定义它,然后在模板中使用new_ansible_var
:
vars:
myDict:
string1: a
string2: b
new_ansible_var: 'myDict[existing_ansible_var | default("this key does not exist in the dict")] | default("") '
【讨论】:
这是一个很好的解决方案!现在我想知道如何在不使用 Jinja 的情况下在 Ansible 中做到这一点...... ... 或者如果我可以在剧本中使用相同的语法/结构并能够在同一剧本中访问new_ansible_var
是的,这也是可能的。我在上面的答案中添加了一个示例。
如果您在编写角色时需要这个,您可以将所需的字典放入角色变量文件vars/main.yml
中的变量中。通常这比包含字典数据和逻辑的一行更容易阅读,并且角色中的代码变得更加不言自明。以上是关于在 Ansible/Jinja2 中设置 var 的 case 语句的主要内容,如果未能解决你的问题,请参考以下文章