自动化运维-ansible中的条件判断
一、when 语句和基础比较运算符
when
语句用于条件性地执行任务。它支持所有常见的比较运算符。
常用运算符:
==
,!=
: 等于,不等于>
,<
,>=
,<=
: 数值比较and
,or
,not
: 逻辑与、或、非is
: 是in
: 检查元素是否存在于列表中
二、变量状态测试
对任务执行的结果进行注册的变量来when:
Defined
:判断变量是否已经定义,已定义则返真Undefined
:判断变量是否已经定义,未定义则返真None
:判断变量值是否为空,如果变量已经定义,但是变量值为空,则返真
yaml
[student@master ansible] vim a.yml
# playbook内容如下
---
- name: test1
hosts: node1
vars:
aa: 11
cc:
tasks:
- name: test11
debug:
msg: 111
when: aa is defined
- name: test12
debug:
msg: 222
when: bb is undefined
- name: test13
debug:
msg: 333
when: cc is none

三、任务执行结果测试
结合 register
使用,用于检查上一个被注册的任务的执行状态
Success/successed
:通过任务的返回信息判断执行状态,任务执行成功返回真Failure/failed
:通过执行任务的返回信息判断执行状态,任务执行失败则返回真Change/changed
:通过任务的返回信息判断执行状态,任务返回状态为changed则返回真Skip/skipped
:通过任务的返回信息判断执行状态,当任务没有满足条件,而被跳过执行
yaml
[student@master ansible] vim b.yml
# playbook内容如下
---
- name: test2
hosts: node1
vars:
aa: 11
tasks:
- name: test21
shell:
cmd: ls /mnt
when: aa == 11
register: yy
- name: test22
debug:
msg: this is success
when: yy is success
- name: test23
debug:
msg: this is failed
when: yy is failed
- name: test24
debug:
msg: this is changed
when: yy is changed
- name: test25
debug:
msg: this is skip
when: yy is skip

四、路径测试
以下 tests
的判断均对 ansible
主机中的路径,与目标主机无关
如果您需要检查目标主机上的路径,请使用 stat
模块先获取信息
file
:判断路径是否是一个文件directory
:判断路径是否是一个目录link
:判断路径是否是一个软连接mount
:判断路径是否是一个挂载点exists
:判断路径是否存在
创建一个目录 /test
创建一个文件 /test/file1
创建一个软连接 /test/softlinka
创建一个硬链接 /test/hardlinka
yaml
[student@master ansible] vim c.yml
# playbook内容如下
---
- name: test3
hosts: node1
vars:
a1: /test/file1
a2: /test/
a3: /test/softlinka
a4: /test/hardlinka
a5: /boot/
tasks:
- name: test31
debug:
msg: this is file
when: a1 is file
- name: test32
debug:
msg: this is directory
when: a2 is directory
- name: test33
debug:
msg: this is softlink
when: a3 is link
- name: test34
debug:
msg: this is hardlink
when: a4 is link
- name: test35
debug:
msg: this is mount
when: a5 is mount
- name: test36
debug:
msg: this is exists
when: a1 is exists

五、字符串测试
注意: 字符串 "123"
是字符串,不是数字。变量 123
是数字
-
lower
:判断包含字母的字符串中的字母是否纯小写 -
upper
:判断包含字母的字符串中的字母是否纯大写 -
string
:判断对象是否是一个字符串 -
number
:判断对象是否一个数字
yaml
[student@master ansible] vim d.yml
# playbook内容如下
---
- name: test4
hosts: node1
vars:
a1: abc
a2: ABC
a3: '123'
a4: 123
tasks:
- name: test41
debug:
msg: this is lower
when: a1 is lower
- name: test42
debug:
msg: this is upper
when: a2 is upper
- name: test43
debug:
msg: this is string
when: a3 is string
- name: test44
debug:
msg: this is number
when: a4 is number

六、block/rescue/always
- 执行
block
成功则直接执行always
- 执行
block
失败则先执行rescue
后再执行always
前提:
在node1、node2上添加一块硬盘,然后新建卷组
Node1的卷组大小为2G 卷组名为research
Node2的卷组大小为1G 卷组名为research
需求:创建一个名为/etc/ansible/lv.yml 的playbook,它将在所有受管节点上运行以执行下列任务:
创建符合以下要求的逻辑卷:
逻辑卷创建在research卷组中
逻辑卷名称为data
逻辑卷大小为1500MiB
使用ext4文件系统格式化逻辑卷
如果无法创建请求的逻辑卷大小,应显示错误消息
Could not create logical volume of that size,并且应改为使用大小 800MiB。
如果卷组research 不存在 ,应显示错误消息
Volume group does not exist,并且不要以任何方式挂载逻辑卷
yaml
[student@master ansible] vim lv.yml
# playbook内容如下
---
- name: lv
hosts: node1,node2
tasks:
- name: lv
block:
- name: lv1500
lvol:
vg: research
lv: data
size: 1500
rescue:
- name: output
debug:
msg: Could not create logical volume of that size
- name: lv800
lvol:
vg: research
lv: data
size: 800
always:
- name: fstype
filesystem:
fstype: ext4
dev: /dev/research/data
when: "'research' in ansible_facts.lvm.vgs"
- name: not research
debug:
msg: Volume group does not exist
when: "'research' not in ansible_facts.lvm.vgs"

七、判断与错误处理
fail模块可用于中断剧本,一般是不会无故中断,在满足条件的情况下可以中断,经常和when一起用
yaml
[student@master ansible] vim f.yml
# playbook内容如下
---
- name: test6
hosts: node1
tasks:
- name: test61
shell:
cmd: echo 'this is a string for testing--error'
register: return_value
- name: test62
fail:
msg: Conditions established,Interrupt running playbook
when: "'error' in return_value.stdout"
- name: test63
debug:
msg: I never execute,because the playbook has stopped

即使命令成功执行,只要满足 failed_when
的条件,任务也会被标记为失败
yaml
[student@master ansible] vim e.yml
# playbook内容如下
---
- name: testi5
hosts: node1
tasks:
- name: test51
debug:
msg: I execute normally
- name: test52
shell:
cmd: echo 'this is a string testing--error'
register: return_value
failed_when: "'error' in return_value.stdout"
- name: test53
debug:
msg: yyy

ignore_errors: yes
跳过错误、忽略错误
yaml
[student@master ansible] vim g.yml
# playbook内容如下
---
- name: test7
hosts: node1
tasks:
- name: test71
debug:
msg: "{{ansible_fqdn}}"
- name: test72
debug:
msg: "{{ansible_ip}}"
ignore_errors: yes
- name: test73
file:
path: /tmp/abc
state: touch

Changed_when
:可以修改任务执行后的最终状态
yaml
[student@master ansible] vim h.yml
# playbook内容如下
---
- name: test8
hosts: node1
tasks:
- name: test8
debug:
msg: "{{ansible_fqdn}}"
changed_when: true

八、if
判断
编写剧本修改远程文件内容
创建剧本 /home/student/ansible/newissue.yml,满足下列要求:
- 在所有清单主机上运行,替换/etc/issue 的内容
- 对于 test01 主机组中的主机,/etc/issue 文件内容为 test01
- 对于 test02 主机组中的主机,/etc/issue 文件内容为 test02
- 对于 web 主机组中的主机,/etc/issue 文件内容为 Webserver
inventory
分组

编辑 playbook
yaml
[student@master ansible] vim newissue.yml
# playbook内容如下
---
- name: newissue
hosts: all
tasks:
- name: t1
copy:
content: |
{% if 'test01' in group_names %}
test01
{% elif 'test02' in group_names %}
test02
{% elif 'web' in group_names %}
Webserver
{% endif %}
dest: /etc/issue

查看 /etc/issue
bash
[student@master ansible] ansible all -m shell -a 'cat /etc/issue'
