Ansible - 如果未定义变量,则使用默认值
Ansible - Use default if a variable is not defined
我在我的角色中自定义 linux users
创建。我需要让我角色的用户自定义 home_directory
、group_name
、name
、password
。
我想知道是否有更灵活的方法来处理默认值。
我知道下面的代码是可行的:
- 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}}"
当 my_variable
未定义时,代码应设置 name="default_name"
。
我可以在 defaults/main.yml
上设置所有变量并像这样创建用户:
- name: Create user
user:
name: "{{my_variable}}"
但是这些变量在一个非常大的散列中,并且该散列中有一些散列不能是默认值。
你可以使用 Jinja 的 default
:
- name: Create user
user:
name: "{{ my_variable | default('default_value') }}"
如果您有一个要循环播放的项目,请在 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) }}"
不完全相关,但您也可以同时检查 undefined
和 empty
(例如 my_variable:
)变量。 (注意:仅适用于 > 1.9 的 ansible 版本,参见:link)
- name: Create user
user:
name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
if my_variable is defined else 'default_value' }}"
如果您使用查找来设置从环境中读取的默认值,您还将默认的第二个参数设置为 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') }}"
如果有人正在寻找处理嵌套变量的选项,github issue 中有几个这样的选项。
简而言之,您需要对每一层嵌套变量使用 "default" 过滤器。对于变量 "a.nested.var",它看起来像:
- hosts: 'localhost'
tasks:
- debug:
msg: "{{ ((a | default({})).nested | default({}) ).var | default('bar') }}"
或者您可以为每个级别的变量设置空字典的默认值,也许使用 "combine" 过滤器。或者使用 "json_query" 过滤器。但是如果你只有一层嵌套,我选择的选项对我来说似乎更简单。
这个问题很老了,但是呢:
- hosts: 'localhost'
tasks:
- debug:
msg: "{{ ( a | default({})).get('nested', {}).get('var','bar') }}"
我觉得没那么麻烦了...
如果您要为布尔值分配默认值,请确保在 default() 中不使用引号。
- name: create bool default
set_fact:
name: "{{ my_bool | default(true) }}"
对于其他变量,使用验证答案中给出的相同方法。
- name: Create user
user:
name: "{{ my_variable | default('default_value') }}"
我在我的角色中自定义 linux users
创建。我需要让我角色的用户自定义 home_directory
、group_name
、name
、password
。
我想知道是否有更灵活的方法来处理默认值。
我知道下面的代码是可行的:
- 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}}"
当 my_variable
未定义时,代码应设置 name="default_name"
。
我可以在 defaults/main.yml
上设置所有变量并像这样创建用户:
- name: Create user
user:
name: "{{my_variable}}"
但是这些变量在一个非常大的散列中,并且该散列中有一些散列不能是默认值。
你可以使用 Jinja 的 default
:
- name: Create user
user:
name: "{{ my_variable | default('default_value') }}"
如果您有一个要循环播放的项目,请在 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) }}"
不完全相关,但您也可以同时检查 undefined
和 empty
(例如 my_variable:
)变量。 (注意:仅适用于 > 1.9 的 ansible 版本,参见:link)
- name: Create user
user:
name: "{{ ((my_variable == None) | ternary('default_value', my_variable)) \
if my_variable is defined else 'default_value' }}"
如果您使用查找来设置从环境中读取的默认值,您还将默认的第二个参数设置为 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') }}"
如果有人正在寻找处理嵌套变量的选项,github issue 中有几个这样的选项。
简而言之,您需要对每一层嵌套变量使用 "default" 过滤器。对于变量 "a.nested.var",它看起来像:
- hosts: 'localhost'
tasks:
- debug:
msg: "{{ ((a | default({})).nested | default({}) ).var | default('bar') }}"
或者您可以为每个级别的变量设置空字典的默认值,也许使用 "combine" 过滤器。或者使用 "json_query" 过滤器。但是如果你只有一层嵌套,我选择的选项对我来说似乎更简单。
这个问题很老了,但是呢:
- hosts: 'localhost'
tasks:
- debug:
msg: "{{ ( a | default({})).get('nested', {}).get('var','bar') }}"
我觉得没那么麻烦了...
如果您要为布尔值分配默认值,请确保在 default() 中不使用引号。
- name: create bool default
set_fact:
name: "{{ my_bool | default(true) }}"
对于其他变量,使用验证答案中给出的相同方法。
- name: Create user
user:
name: "{{ my_variable | default('default_value') }}"