本来打算自己写一波 ansible 系列的,后来发现一老哥写的太好了,「点击此处直达」,我这里也就边看边对该系列文章做下笔记,方便以后查阅,ansible 入门的话墙裂建议阅读前方链接博文~~~
在 ansible 中,条件判断的关键字是 when
,使用 when
关键字为任务指定条件,条件成立,则执行任务,条件不成立,则不执行任务。
在
when
关键字中引用变量时,变量名不需要加{{ }}
。
字符串判断
在 ansible 中使用 ==
就可以判断字符串是否相同,还可通过如下关键字判断字符串大小写的状态:
lower
:判断包含字母的字符串中的字母是否是纯小写,字符串中的字母全部为小写则返回真;upper
:判断包含字母的字符串中的字母是否是纯大写,字符串中的字母全部为大写则返回真;
除此之外,还可通过 in
关键字判断指定字符串是否存在于另一个字符串中。
例 1:判断当前操作主机的系统是不是 CentOS。
---
- hosts: all
tasks:
- debug:
msg: "System release is CentOS"
when: ansible_distribution == "CentOS"
例 2:判断给定字符串的大小写状态。
---
- hosts: B
gather_facts: no
vars:
str1: "abc"
str2: "ABC"
tasks:
- debug:
msg: "This string is all lowercase"
when: str1 is lower
- debug:
msg: "This string is all uppercase"
when: str2 is upper
例 3:判断给定字符串变量值是否存在于 hello world
字符串中。
---
- hosts: B
gather_facts: no
vars:
str1: "hello"
str2: "hello world"
tasks:
- debug:
msg: "{{str1}} in {{str2}}"
when: str1 in str2
运算符判断
在 ansible 中,我们可以使用如下比较运算符:
==
:比较两个对象是否相等,相等为真;!=
:比较两个对象是否不等,不等为真;>
:比较两个值的大小,如果左边的值大于右边的值,则为真;<
:比较两个值的大小,如果左边的值小于右边的值,则为真;>=
:比较两个值的大小,如果左边的值大于右边的值或左右相等,则为真;<=
:比较两个值的大小,如果左边的值小于右边的值或左右相等,则为真;
我们总结的这些运算符其实都是 jinja2 的运算符,ansible 使用 jinja2 模板引擎,在 ansible 中也可以直接使用 jinja2 的这些运算符。
说完了比较运算符,再来说说逻辑运算符,可用的逻辑运算符如下
and
:逻辑与,当左边与右边同时为真,则返回真;or
:逻辑或,当左边与右边有任意一个为真,则返回真;not
:取反,对一个操作体取反;( )
:组合,将一组操作体包装在一起,形成一个较大的操作体;
例 1:输出大于 2
的数字。
---
- hosts: B
gather_facts: no
tasks:
- debug:
var: item
when: item > 2
with_items: [ 1, 2, 3 ]
例 2:判断客户机系统是否是 CentOS 7。
---
- hosts: all
tasks:
- debug:
msg: "System release is centos7"
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
# 这里的 when 条件也可写为如下:
# when:
# - ansible_distribution == "CentOS"
# - ansible_distribution_major_version == "7"
# 其含义为列表中每一项结果都为 true 时才执行。
例 3:判断任务是否成功执行。
---
- hosts: B
gather_facts: no
tasks:
- name: task1
shell: "ls /testabc"
register: returnmsg
ignore_errors: true
# 如果任务执行失败 ansible 默认会立即停止继续往下执行,使用 ignore_errors 可以忽略失败的错误,让其正常向下执行
- name: task2
debug:
msg: "Command execution successful"
when: returnmsg.rc == 0
- name: task3
debug:
msg: "Command execution failed"
when: returnmsg.rc != 0
文件判断
ansible 可通过如下关键字对文件状态进行判断:
file
:判断路径是否是一个文件,如果路径是一个文件则返回真;directory
:判断路径是否是一个目录,如果路径是一个目录则返回真;link
:判断路径是否是一个软链接,如果路径是一个软链接则返回真;mount
:判断路径是否是一个挂载点,如果路径是一个挂载点则返回真;exists
:判断路径是否存在,如果路径存在则返回真;
注意哦,这里的文件路径是 ansible 管理机的路径。
例:判断 /testdir
是否存在。
---
- hosts: B
gather_facts: no
vars:
testpath: /testdir
tasks:
- debug:
msg: "file exist"
when: testpath is exists
# 取反可使用 not,下面判断表示 testpath 路径是否不存在
# when: testpath is not exists
变量判断
ansible 可通过如下几个关键字对变量进行判断:
string
:判断对象是否是一个字符串,是字符串则返回真;number
:判断对象是否是一个数字,是数字则返回真;defined
:判断变量是否已经定义,已经定义则返回真;undefind
:判断变量是否已经定义,未定义则返回真;none
:判断变量值是否为空,如果变量已经定义,但是变量值为空,则返回真;
例 1:当对应的条件为真时,你可以看到 debug 模块对应的输出。
---
- hosts: B
gather_facts: no
vars:
testvar: "test"
testvar1:
tasks:
- debug:
msg: "Variable is defined"
when: testvar is defined
- debug:
msg: "Variable is undefined"
when: testvar2 is undefined
- debug:
msg: "The variable is defined, but there is no value"
when: testvar1 is none
例 2:判断给定变量是一个字符串还是数字。
---
- hosts: B
gather_facts: no
vars:
testvar: "a"
tasks:
- debug:
msg: "{{testvar}} is a number"
when: testvar is number
- debug:
msg: "{{testvar}} is a string"
when: testvar is string
结果判断
ansible 可通过如下几个关键字来对任务的执行结果进行判断:
success
或succeeded
:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真;failure
或failed
:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真;change
或changed
:通过任务的返回信息判断任务的执行状态,任务执行状态为 changed 则返回真;skip
或skipped
:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真;
例:根据任务执行结果输出对应信息。
---
- hosts: B
gather_facts: no
vars:
doshell: "yes"
tasks:
- shell: "cat /testdir/abc"
when: doshell == "yes"
register: returnmsg
ignore_errors: true
- debug:
msg: "success"
when: returnmsg is success
- debug:
msg: "failed"
when: returnmsg is failure
- debug:
msg: "changed"
when: returnmsg is change
- debug:
msg: "skip"
when: returnmsg is skip
整除判断
ansible 可通过如下关键字对一个数字进行整除判断:
even
:判断数值是否是偶数,是偶数则返回真;odd
:判断数值是否是奇数,是奇数则返回真;divisibleby(num)
:判断是否可以整除指定的数值,如果除以指定的值以后余数为0,则返回真;
看如下示例:
---
- hosts: B
gather_facts: no
vars:
num1: 4
num2: 7
num3: 64
tasks:
- debug:
msg: "An even number"
when: num1 is even
- debug:
msg: "An odd number"
when: num2 is odd
- debug:
msg: "Can be divided exactly by 8"
when: num3 is divisibleby(8)
列表父子集判断
ansible 可使用如下关键字对列表进行父子集判断:
subset
:判断一个 list 是不是另一个 list 的子集,是另一个 list 的子集时返回真;superset
: 判断一个 list 是不是另一个 list 的父集,是另一个 list 的父集时返回真;
看如下示例:
---
- hosts: B
gather_facts: no
vars:
a:
- 2
- 5
b: [1,2,3,4,5]
tasks:
- debug:
msg: "A is a subset of B"
when: a is subset(b)
- debug:
msg: "B is the parent set of A"
when: b is superset(a)
版本判断
在 ansible 中 version
关键字可以用于对比两个版本号的大小,或者与指定的版本号进行对比,使用语法为 version('版本号', '比较操作符')
。
version
支持的比较操作符如下:
- 大于:
>
、gt
; - 大于等于:
>=
、ge
- 小于:
<
、lt
; - 小于等于:
<=
、le
; - 等于:
==
、=
、eq
; - 不等于:
!=
、<>
、ne
;
看如下示例:
---
- hosts: B
vars:
ver: 7.4.1708
ver1: 7.4.1707
tasks:
- debug:
msg: "This message can be displayed when the ver is greater than ver1"
when: ver is version(ver1,">")
- debug:
msg: "system version {{ansible_distribution_version}} greater than 7.3"
when: ansible_distribution_version is version("7.3","gt")
# ver_val is version(ver1, ">") 表示 ver_val 是否大于 ver1 版本
合并判断
在 ansible 中,可以使用 block
关键字将多个任务整合成一个块,这个块将被当做一个整体,我们可以对这个块添加判断条件,当条件成立时,则执行这个块中的所有任务。
我们来看一个小示例,如下:
---
- hosts: B
gather_facts: no
tasks:
- debug:
msg: "task1 not in block"
- block:
- debug:
msg: "task2 in block1"
- debug:
msg: "task3 in block1"
when: 2 > 1
状态判断
failed_when
的作用就是,当对应的条件成立时,将对应任务的执行状态设置为失败,我们可以借助 failed_when
关键字来完成类似 fail
模块的功能。
看下面示例:
---
- hosts: B
gather_facts: no
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"
上例中,failed_when
对应的条件是 "error" in return_value.stdout
,表示 error
字符串如果存在于 shell 模块执行后的标准输出中,则条件成立,当条件成立后,shell 模块的执行状态将会被设置为失败,由于 shell 模块的执行状态被设置为失败,所以 playbook 会终止运行,于是,最后的 debug 模块并不会被执行。
理解了' failed_when'关键字以后,顺势理解'changed_when'关键字就容易多了。
failed_when
关键字的作用是在条件成立时,将对应任务的执行状态设置为失败。
changed_when
关键字的作用是在条件成立时,将对应任务的执行状态设置为 changed
。
有了前文作为基础,就不再对 changed_when
做过多解释了,我们直接来看一个小示例:
---
- hosts: B
gather_facts: no
tasks:
- debug:
msg: "test message"
changed_when: 2 > 1
我们知道,debug 模块在正常执行的情况下只能是 ok
状态,上例中,我们使用 changed_when
关键字将 debug 模块的执行后的状态定义为了 changed
,你可以尝试执行上例 playbook,执行效果如下:
$ ansible-playbook test.yml
PLAY [B] ******************************************************************************************************************************
TASK [debug] **************************************************************************************************************************
changed: [B] => {
"msg": "test message"
}
PLAY RECAP ****************************************************************************************************************************
B : ok=1 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
前文中总结过 handlers 的用法,我们知道,只有任务作出了实际的操作时(执行后状态为 changed
),才会真正的执行对应的handlers,而在某些时候,如果想要通过任务执行后的返回值将任务的最终执行。
其实,changed_when
除了能够在条件成立时将任务的执行状态设置为 changed
,还能让对应的任务永远不能是 changed
状态,示例如下:
---
- hosts: B
gather_facts: no
tasks:
- shell: "ls /opt"
changed_when: false
当将 changed_when
直接设置为 false
时,对应任务的状态将不会被设置为 changed
,如果任务原本的执行状态为 changed
,最终则会被设置为 ok
,所以,上例 playbook 执行后,shell 模块的执行状态最终为 ok
。
评论区