Ansible-如果未定义变量,请使用默认值


98

我正在自定义users角色中的linux 创建。我需要让我的角色定制的用户home_directorygroup_namenamepassword

我想知道是否有更灵活的方式来应对默认值。

我知道以下代码是可能的:

- name: Create default
  user:
    name: "default_name"
  when: my_variable is not defined

 - name: Create custom
  user:
    name: "{{my_variable}}"
  when: my_variable is defined

但是正如我提到的,有很多可选变量,这创造了很多可能性。

是否有类似上面的代码?

user:
  name: "default_name", "{{my_variable}}"

该代码应name="default_name"my_variable未定义时设置。

我可以设置所有变量defaults/main.yml并像这样创建用户:

- name: Create user
  user:
    name: "{{my_variable}}"

但是这些变量在一个非常大的散列中,并且该散列中有一些哈希不能为默认值。


Answers:


190

您可以使用Jinja的default

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"

10
并且如果默认变量依赖于另一个变量。例如default('/home/' {{ anothervar }}),是否有一种方法可以串联这些值?
贝尔纳多·维尔

8
只需删除'周围的' default_value,它将使用一个名为default_value的变量
dagonza

7
如果变量嵌套为,则无效{{ dict.key | default(5) }}。如果dict未定义,它将失败。
乔丹·斯图尔特

1
仅供参考,这现在将引发错误:[WARNING]: when statements should not include jinja2 templating delimiters such as {{ }} or {% %}.
布莱恩·肯尼迪

1
@JordanStewart我有同样的情况-带有嵌套变量。我在下面发布了答案以及可能的解决方案。
罗曼·克鲁格洛夫

11

并不完全相关,但是您也可以检查两个undefinedAND empty(例如my_variable:)变量。(注意:仅适用于ansible版本> 1.9,请参见:链接

- name: Create user
  user:
    name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
    if my_variable is defined else 'default_value' }}"

2
这很棒,非常有用。
eagle33322 '19

5

如果有人正在寻找一个处理嵌套变量的选项,那么这个github问题中有几个这样的选项

简而言之,您需要为每个级别的嵌套var使用“默认”过滤器。对于变量“ a.nested.var”,它看起来像:

- hosts: 'localhost'
  tasks:
    - debug:
        msg: "{{ ((a | default({})).nested | default({}) ).var | default('bar') }}"

或者您可以为每个变量级别设置空字典的默认值,也可以使用“组合”过滤器。或使用“ json_query”过滤器。但是,如果您只有一层嵌套,那么我选择的选项似乎更简单。


4

如果您有一个要播放的项目,请在group_vars / all或其他有意义的地方定义该列表:

all_items:
  - first
  - second
  - third
  - fourth

然后您的任务可以如下所示:

  - name: List items or default list
    debug:
      var: item
    with_items: "{{ varlist | default(all_items) }}"

传递varlist作为JSON数组:

ansible-playbook <playbook_name> --extra-vars='{"varlist": [first,third]}'

在此之前,您可能还需要一个任务来检查varlist中的每个项目是否也在all_items中

  - name: Ensure passed variables are in all_items
    fail:
      msg: "{{ item }} not  in all_items list"
    when: item not in all_items
    with_items: "{{ varlist | default(all_items) }}"

3

如果使用查找来设置从环境读取的默认值,则还需要将default的第二个参数设置为true:

- set_facts:
    ansible_ssh_user: "{{ lookup('env', 'SSH_USER') | default('foo', true) }}"

您还可以串联多个默认定义:

- set_facts:
    ansible_ssh_user: "{{ some_var.split('-')[1] | default(lookup('env','USER'), true) | default('foo') }}"

1

这个问题已经很老了,但是:

- hosts: 'localhost'
  tasks:
    - debug:
        msg: "{{ ( a | default({})).get('nested', {}).get('var','bar') }}"

对我来说看起来不那么麻烦。


1

如果要为布尔事实分配默认值,请确保在default()中不使用引号。

- name: create bool default
  set_fact:
    name: "{{ my_bool | default(true) }}"

对于其他变量,请使用经过验证的答案中给出的相同方法。

- name: Create user
  user:
    name: "{{ my_variable | default('default_value') }}"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.