我想在Ansible剧本中有条件地定义一个变量,如下所示:my_var: "{{ 'foo' if my_condition}}"
。如果条件没有解析为真,我希望变量保持未定义。
如果我尝试这样做,Ansible会出错:
fatal: [foo.local] => {'msg': 'AnsibleUndefinedVariable: One or more undefined variables: the inline if-expression on line 1 evaluated to false and no else section was defined.', 'failed': True}
。为什么这仍然是一个错误?
完整的案例如下:{role: foo, my_var: "foo"}
。如果定义了my_var
,则该角色会执行一些特殊操作。在某些情况下,我不希望角色这样做。我可以使用when: condition
,但是我必须复制整个角色块。我也可以使用一个额外的bool变量,但我想要一个解决方案而不必更改"界面"这个角色。
有什么想法吗?
答案 0 :(得分:30)
您可以使用以下内容:my_var: "{{ 'foo' if my_condition else '' }}"
。如果条件不匹配,则会发生'else',在这种情况下,将为变量设置一个空值。我认为这是一个简短,易读且优雅的解决方案。
答案 1 :(得分:19)
此代码可帮助您定义带条件的变量。
- hosts: node1
gather_facts: yes
tasks:
- name: Check File
shell: ls -ld /etc/postfix/post-install
register: result
ignore_errors: yes
- name: Define Variable
set_fact:
exists: "{{ result.stdout }}"
when: result|success
- name: Display Variable
debug: msg="{{ exists }}"
ignore_errors: yes
所以这里只有条件为真时才会显示“存在”。
答案 2 :(得分:3)
我相信你是在default(omit)
过滤器之后。
http://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#omitting-parameters
根据示例,模式的行为类似于循环中前两个项目的设置。
- name: touch files with an optional mode
file:
dest: "{{item.path}}"
state: touch
mode: "{{item.mode|default(omit)}}"
loop:
- path: /tmp/foo
- path: /tmp/bar
- path: /tmp/baz
mode: "0444"
答案 3 :(得分:0)
我的示例,在https://stackoverflow.com/a/43403229/5025060之后:
vars:
sudoGroup: "{{ 'sudo' if ansible_distribution == 'Ubuntu' else 'wheel' }}"
由于Ubuntu与其他平台使用了不同的sudo约定,因此我告诉Ansible如果平台是Ubuntu,则将名为sudoGroup
的变量设置为sudo
,否则将其设置为{{1 }}。
稍后,在我的剧本中,我将变量与Ansible的wheel
模块结合在一起,以根据运行的操作系统Ansible将user
或sudo
添加到帐户的辅助组中:>
wheel
注释:
- name: Add or update bob account
user:
name: bob
uid: 3205
groups: "{{ sudoGroup }}"
append: yes
定义中,必须在{{ variable }}
周围加上user: groups:
部分中定义了sudoGroup
,Ansible就会在运行时(基于vars:
)为我在{{1}中定义的每个目标配置它}部分。