Ansible系列基础篇 1.7.2、PlayBook之条件判断
一、条件判断基础定义
功能:条件判断,使用when关键字为任务指定条件,条件成立,则执行任务,条件不成立,则不执行任务。
- 在when关键字中引用变量时,变量名不需要加"{{ }}"
基础使用示例如下:
---
- hosts: test70
remote_user: root
tasks:
- debug:
msg: "System release is centos"
when: ansible_distribution == "CentOS"
二、逻辑运算符 比较运算符
2.1、逻辑运算符
== :比较两个对象是否相等,相等为真 != :比较两个对象是否不等,不等为真 > :比较两个值的大小,如果左边的值大于右边的值,则为真 < :比较两个值的大小,如果左边的值小于右边的值,则为真 >= :比较两个值的大小,如果左边的值大于右边的值或左右相等,则为真 <= :比较两个值的大小,如果左边的值小于右边的值或左右相等,则为真 运算符其实都是jinja2的运算符,ansible使用jinja2模板引擎,在ansible中也可以直接使用jinja2的这些运算符。
# 示例 --- - hosts: test70 remote_user: root gather_facts: no tasks: - debug: msg: "{{ item }}" with_items: - 1 - 2 - 3 when: item > 1
2.2、比较运算符
and :逻辑与,当左边与右边同时为真,则返回真 or :逻辑或,当左边与右边有任意一个为真,则返回真 not :取反,对一个操作体取反 ( ) :组合,将一组操作体包装在一起,形成一个较大的操作体
# 示例, and --- - hosts: test70 remote_user: root tasks: - debug: msg: "System release is centos7" when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7" # 示例,and语法的另一种写法。类似列表 --- - hosts: test70 remote_user: root tasks: - debug: msg: "System release is centos7" when: - ansible_distribution == "CentOS" - ansible_distribution_major_version == "7" # 示例,逻辑与、逻辑或、分组组合 --- - hosts: test70 remote_user: root tasks: - debug: msg: "System release is centos6 or centos7" when: ansible_distribution == "CentOS" and (ansible_distribution_major_version == "6" or ansible_distribution_major_version == "7") # 示例,取反 --- - hosts: test70 remote_user: root tasks: - debug: msg: "System release is not centos" when: not ansible_distribution == "CentOS" # 示例,从上个task上的返回结果,判断 --- - hosts: test70 remote_user: root tasks: - name: task1 shell: "ls /testabc" register: returnmsg - name: task2 debug: msg: "Command execution successful" when: returnmsg.rc == 0 - name: task3 debug: msg: "Command execution failed" when: returnmsg.rc != 0
三、ignore_errors
# 无ignore_errors,因为没有testabc目录,执行‘ ls /testabc ’命令,会有错误信息。 --- - hosts: test70 remote_user: root tasks: - name: task1 shell: "ls /testabc" register: returnmsg - name: task2 debug: msg: "Command execution successful" when: returnmsg.rc == 0 - name: task3 debug: msg: "Command execution failed" when: returnmsg.rc != 0
执行结果:
加上ignore_errors时,忽略该命令的错误,示例如下:
---
- hosts: test70
remote_user: root
tasks:
- name: task1
shell: "ls /testabc"
register: returnmsg
ignore_errors: true
- name: task2
debug:
msg: "Command execution successful"
when: returnmsg.rc == 0
- name: task3
debug:
msg: "Command execution failed"
when: returnmsg.rc != 0
四、高级判断 tests
4.1、exists
功能:判断是否存在。
--- - hosts: test70 remote_user: root gather_facts: no vars: testpath: /testdir tasks: - debug: msg: "file exist" when: testpath is exists
# 判断是否不存在,方式一 --- - hosts: test70 remote_user: root gather_facts: no vars: testpath: /testdir tasks: - debug: msg: "file exist" when: testpath is not exists # 判断是否不存在,方式二 --- - hosts: test70 remote_user: root gather_facts: no vars: testpath: /testdir tasks: - debug: msg: "file exist" when: not testpath is exists
4.2、判断变量的tests. defined undefined none
4.2、判断执行结果的tests. success failure change skip
4.3、判断路径的tests. file directory link mount exists
4.4、判断字符串的tests. lower upper
4.5、判断整除的tests. even odd divisibleby
4.6、其他的tests
五、blcok
5.1、block基础使用
当when条件成立时,需要执行多个任务,而不是像之前的,只执行一个任务,这时候就需要用到‘block’关键字。
"block"关键字将多个任务整合成一个"块",这个"块"将被当做一个整体,我们可以对这个"块"添加判断条件,当条件成立时,则执行这个块中的所有任务,示例如下:
--- - hosts: test70 remote_user: root tasks: - debug: msg: "task1 not in block" - block: - debug: msg: "task2 in block1" - debug: msg: "task3 in block1" when: 2 > 1
5.2、block与rescue
下面示例,定义了一个block,这个block中有一个任务,这个任务在目标主机中执行了'ls /ooo'命令,除了block关键字,还有另外一个关键字rescue,rescue关键字与block关键字对齐,rescue的字面意思为"救援",表示当block中的任务执行失败时,会执行rescue中的任务进行补救,当然,在rescue中定义什么任务,是由你决定的,上述示例主要是为了说明,当block中的任务出错时,会执行rescue中的任务,当block中的任务顺利执行时,则不会执行rescue中的任务。
# 故障错误判断
---
- hosts: test70
remote_user: root
tasks:
- shell: 'ls /ooo'
register: return_value
ignore_errors: true
- debug:
msg: "I cought an error"
when: return_value is failed
# 故障错误判断,用block关键字实现
---
- hosts: test70
remote_user: root
tasks:
- block:
- shell: 'ls /ooo'
rescue:
- debug:
msg: 'I caught an error'
5.3、block与always
always关键字以后,无论block中的任务执行成功还是失败,always中的任务都会被执行,示例如下:
---
- hosts: test70
remote_user: root
tasks:
- block:
- debug:
msg: 'I execute normally'
- command: /bin/false
- debug:
msg: 'I never execute, due to the above task failing'
rescue:
- debug:
msg: 'I caught an error'
- command: /bin/false
- debug:
msg: 'I also never execute'
always:
- debug:
msg: "This always executes"
tip: block、rescue、always下,都可以定义多个任务。
六、fail模块
执行到fail模块时,停止任务执行。
# 基础使用方式一 --- - hosts: test70 remote_user: root tasks: - debug: msg: "1" - debug: msg: "2" - fail: - debug: msg: "3" - debug: msg: "4" # 基础使用方式二 --- - hosts: test70 remote_user: root tasks: - debug: msg: "1" - fail: msg: "Interrupt running playbook" - debug: msg: "2"
人为判断,出现异常,停止服务,示例如下:
---
- hosts: test70
remote_user: root
tasks:
- shell: "echo 'This is a string for testing--error'"
register: return_value
- fail:
msg: "Conditions established,Interrupt running playbook"
when: "'error' in return_value.stdout"
- debug:
msg: "I never execute,Because the playbook has stopped"
七、特殊的when,failed_when changed_when
7.1、failed_when
功能:在条件成立时,将对应任务的执行状态设置为失败,停止执行脚本;
当' failed_when'关键字对应的条件成立时,' failed_when'会将对应的任务的执行状态设置为失败,以停止playbook的运行,但是需要注意的时,' failed_when'虽然会将任务的执行状态设置为失败,但是并不代表任务真的失败了,就以上例来说,上例的shell模块的确是完全正常的执行了,只不过在执行之后,' failed_when'对应的条件成立了,' failed_when'将shell模块的执行状态设置为失败而已,所以,' failed_when'并不会影响shell模块的执行过程,只会在条件成立时影响shell模块最终的执行状态,以便停止playbook的运行。
---
- hosts: test70
remote_user: root
tasks:
- debug:
msg: "I execute normally"
- shell: "echo 'This is a string for testing error'"
register: return_value
failed_when: ' "error" in return_value.stdout'
- debug:
msg: "I never execute,Because the playbook has stopped"
7.2、changed_when
功能:在条件成立时,将对应任务的执行状态设置为changed
--- - hosts: test70 remote_user: root tasks: - debug: msg: "test message" changed_when: 2 > 1
让任务永远不能是changed状态,示例如下:
--- - hosts: test70 remote_user: root tasks: - shell: "ls /opt" changed_when: false