06. 条件
1. when 语句⚓
when
语句就是条件语句。
该语句可以包含不带双花括号的原生的 Jinja2 表达式:
tasks:
- name: "shut down Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_facts['os_family'] == "Debian"
Important
所有的变量都可以在when
字句中像这样不带双花括号直接使用!
还可以使用括号对条件进行分组:
when: (ansible_facts['distribution'] == "CentOS" and ansible_facts['distribution_major_version'] == "6") or
(ansible_facts['distribution'] == "Debian" and ansible_facts['distribution_major_version'] == "7")
若需要满足多个条件还可以这样写:
when:
- ansible_facts['distribution'] == "CentOS"
- ansible_facts['distribution_major_version'] == "6"
还能使用很多的 Jinja2 “tests” and “filters”,其中一些是 ansible 提供的:
tasks:
- command: /bin/false
register: result
ignore_errors: True
- command: /bin/something
when: result is failed
# In older versions of ansible use ``success``, now both are valid but succeeded uses the correct tense.
- command: /bin/something_else
when: result is succeeded
- command: /bin/still/something_else
when: result is skipped
在 playbooks 或 inventory 中定义的变量也能使用,仅需要注意使用|bool
过滤器来应用到你想要的一些值上面:
vars:
epic: true
monumental: "yes"
tasks:
- shell: echo "This certainly is epic!"
when: epic or monumental|bool
# or
tasks:
- shell: echo "This certainly isn't epic!"
when: not epic
判断是否定义了变量:
tasks:
- shell: echo "I've got '{{ foo }}' and am not afraid to use it!"
when: foo is defined
- fail: msg="Bailing out. this play requires 'bar'"
when: bar is undefined
2. 条件导入⚓
静态导入会将条件应用到被导入的文件中每个 task 身上。动态导入则不会。
所以静态导入适合每个 task 都适用于同一个条件的情况。
例如:
# main.yml
- import_tasks: other_tasks.yml # note "import"
when: x is not defined
# other_tasks.yml
- set_fact:
x: foo
- debug:
var: x
在导入之后相当于:
- set_fact:
x: foo
when: x is not defined
- debug:
var: x
when: x is not defined
当 set_fact 被执行后, debug 就不会再执行了。使用 include_tasks 即可解决该问题。
3. 根据变量选择文件与模板⚓
可以根据变量名的不同导入不同的文件:
---
- hosts: all
remote_user: root
vars_files:
- "vars/common.yml"
- [ "vars/{{ ansible_facts['os_family'] }}.yml", "vars/os_defaults.yml" ]
tasks:
- name: make sure apache is started
service: name={{ apache }} state=started
若是 Red Hat 操作系统,ansible 会先试图导入 vars/RedHat.yml 文件,若没有该文件则导入 vars/os_defaults.yml 文件,若还没有则抛出错误。
- name: template a file
template:
src: "{{ item }}"
dest: /etc/myapp/foo.conf
loop: "{{ query('first_found', { 'files': myfiles, 'paths': mypaths}) }}"
vars:
myfiles:
- "{{ansible_facts['distribution']}}.conf"
- default.conf
mypaths: ['search_location_one/somedir/', '/opt/other_location/somedir/']
找到第一个可用文件作为模板。