1. 单条件when
tasks:
- name: "shut down Debian flavored systems"
command: /sbin/shutdown -t now
when: ansible_os_family == "Debian"
(当操作系统为debian时就执行关机操作)
---
- hosts: webserver
user: admin
become: yes
vars:
- username: user01
tasks:
- name: create {{ username }} user
user: name={{ username }}
when: ansible_fqdn == "node2.51yuki.cn"
2. 多条件when
---
- hosts: webserver
user: admin
become: yes
tasks:
- name: host 192.168.20.138 run this task
debug: msg="{{ansible_default_ipv4.address}}"
when: ansible_default_ipv4.address == "192.168.20.138"
- name: all host run this task
shell: hostname
register: info
- name: hostname is node2 run this task
debug: msg="{{ansible_fqdn}}"
when: info['stdout']=="node2.51yuki.cn"
tasks:
- name: "shut down CentOS 6 systems"
command: /sbin/shutdown -t now
when:
- ansible_distribution == "CentOS"
- ansible_distribution_major_version == "6"
3. when使用变量进行判断
vars:
epic: true
tasks:
- shell: echo "This certainly is epic!"
when: epic
4. 与循环一起使用when
tasks:
- command: echo {{ item }}
with_items: [ 0, 2, 4, 6, 8, 10 ]
when: item > 5
---
- hosts: test70
remote_user: root
gather_facts: no
tasks:
- debug:
msg: "{{ item }}"
with_items:
- 1
- 2
- 3
when: item > 1
5. 角色包含使用when
- include: tasks/sometasks.yml
when: "'reticulating splines' in output"
- hosts: webservers
roles:
- { role: debian_stock_config, when: ansible_os_family == 'Debian' }
6. 关系、逻辑运算符
6.1 关系运算符
== :比较两个对象是否相等,相等为真
!= :比较两个对象是否不等,不等为真
> :比较两个值的大小,如果左边的值大于右边的值,则为真
< :比较两个值的大小,如果左边的值小于右边的值,则为真
>= :比较两个值的大小,如果左边的值大于右边的值或左右相等,则为真
<= :比较两个值的大小,如果左边的值小于右边的值或左右相等,则为真
我们总结的这些运算符其实都是jinja2的运算符,ansible使用jinja2模板引擎,在ansible中也可以直接使用jinja2的这些运算符。
6.2 逻辑运算符
and :逻辑与,当左边与右边同时为真,则返回真
or :逻辑或,当左边与右边有任意一个为真,则返回真
not :取反,对一个操作体取反
( ) :组合,将一组操作体包装在一起,形成一个较大的操作体
6.3 运算符操作示例
---
- hosts: test70
remote_user: root
tasks:
- debug:
msg: "System release is centos7"
when: ansible_distribution == "CentOS" and ansible_distribution_major_version == "7"
---
- 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"
shell模块在远程主机test70中执行命令 “ls /testabc”,将shell模块的返回值注册到了变量returnmsg,然后通过returnmsg获取到了命令执行的返回码,如果返回码为 0,则证明命令完全正常执行,如果返回码不为0,则证明命令执行时出错了 。
---
- 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表示即使当前task执行报错,ansible也会忽略这个错误,继续执行playbook。
---
- 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
7. is 运算符
---
- hosts: test70
remote_user: root
gather_facts: no
vars:
testpath: /testdir
tasks:
- debug:
msg: "file exist"
when: testpath is exists
vars:
testpath: /testdir1
tasks:
- debug:
msg: "file not exist"
when: testpath is not exists
vars:
testpath: /testdir1
tasks:
- debug:
msg: "file not exist"
when: not testpath is exists
defined :判断变量是否已经定义,已经定义则返回真
undefind :判断变量是否已经定义,未定义则返回真
none :判断变量值是否为空,如果变量已经定义,但是变量值为空,则返回真
---
- hosts: test70
remote_user: root
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
success 或 succeeded:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真
failure 或 failed:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真
change 或 changed:通过任务的返回信息判断任务的执行状态,任务执行状态为changed则返回真
skip 或 skipped:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真
---
- hosts: test70
remote_user: root
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
file : 判断路径是否是一个文件,如果路径是一个文件则返回真
directory :判断路径是否是一个目录,如果路径是一个目录则返回真
link :判断路径是否是一个软链接,如果路径是一个软链接则返回真
mount:判断路径是否是一个挂载点,如果路径是一个挂载点则返回真
exists:判断路径是否存在,如果路径存在则返回真
上述test名均为2.6版本中的名称,在2.5版本之前某些test需要加上"is_"前缀
---
- hosts: test70
remote_user: root
gather_facts: no
vars:
testpath1: "/testdir/test"
testpath2: "/testdir/"
testpath3: "/testdir/testsoftlink"
testpath4: "/testdir/testhardlink"
testpath5: "/boot"
tasks:
- debug:
msg: "file"
when: testpath1 is file
- debug:
msg: "directory"
when: testpath2 is directory
- debug:
msg: "link"
when: testpath3 is link
- debug:
msg: "link"
when: testpath4 is link
- debug:
msg: "mount"
when: testpath5 is mount
- debug:
msg: "exists"
when: testpath1 is exists
lower:判断包含字母的字符串中的字母是否是纯小写,字符串中的字母全部为小写则返回真。
upper:判断包含字母的字符串中的字母是否是纯大写,字符串中的字母全部为大写则返回真。
---
- hosts: test70
remote_user: root
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
even :判断数值是否是偶数,是偶数则返回真
odd :判断数值是否是奇数,是奇数则返回真
divisibleby(num) :判断是否可以整除指定的数值,如果除以指定的值以后余数为0,则返回真
---
- hosts: test70
remote_user: root
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"
when: num3 is divisibleby(8)
version:可以用于对比两个版本号的大小,或者与指定的版本号进行对比,使用语法为 version(‘版本号’, ‘比较操作符’)。2.5版本中此tests从version_compare更名为version。
---
- hosts: test70
remote_user: root
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")
第一个task中,当ver的版本号大于ver1时,返回真,条件成立,debug模块输出"This message can be displayed when the ver is greater than ver1"
第二个task中,当facts中的ansible_distribution_version的值大于7.3时,返回真,条件成立,debug模块输出对应信息
">“与"gt"都表示"大于”,当使用version时,支持多种风格的比较操作符,version支持的比较操作符如下
大于:>, gt
大于等于:>=, ge
小于:<, lt
小于等于:<=, le
等于: ==, =, eq
不等于:!=, <>, ne
subset:判断一个list是不是另一个list的子集,是另一个list的子集时返回真。
superset : 判断一个list是不是另一个list的父集,是另一个list的父集时返回真。
2.5版本中上述两个tests从issubset和issuperset更名为subset和superset。
---
- hosts: test70
remote_user: root
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)
string:判断对象是否是一个字符串,是字符串则返回真。
---
- hosts: test70
remote_user: root
gather_facts: no
vars:
testvar1: 1
testvar2: "1"
testvar3: a
tasks:
- debug:
msg: "This variable is a string"
when: testvar1 is string
- debug:
msg: "This variable is a string"
when: testvar2 is string
- debug:
msg: "This variable is a string"
when: testvar3 is string
number:判断对象是否是一个数字,是数字则返回真。
---
- hosts: test70
remote_user: root
gather_facts: no
vars:
testvar1: 1
testvar2: "1"
testvar3: 00.20
tasks:
- debug:
msg: "This variable is number"
when: testvar1 is number
- debug:
msg: "This variable is a number"
when: testvar2 is number
- debug:
msg: "This variable is a number"
when: testvar3 is number
8. 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
"错误处理"功能就是当某任务出错时,执行指定的其他任务,打个比方,想要在A任务执行失败时执行B任务,如果A任务执行成功,则无需执行B任 务,实现这个功能,就能够使用block,当然,还有一些别的方法,也可以实现类似的功能,比如前文中提到的jinja2的tests,有个一名为 failed的test,借助failed也可以实现类似的功能。
---
- 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关键字,还有另外一个关键字rescue,rescue关键字与block关键字对齐,rescue的字面意思为"救 援",表示当block中的任务执行失败时,会执行rescue中的任务进行补救,当block中的任务顺利执行时,则不会执行rescue中的任务。
---
- hosts: test70
remote_user: root
tasks:
- block:
- shell: 'ls /ooo'
rescue:
- debug:
msg: 'I caught an error'
block中有三个任务,这三个任务中的任何一个任务出错,都会执行rescue中的任务,所以通常,我们会使用block和 rescue结合,完成"错误捕捉,报出异常"的功能,其实,不仅block中可以有多个任务,rescue中也可以定义多个任务,当block中的任何 一个任务出错时,会按照顺序执行rescue中的任务。
---
- hosts: test70
remote_user: root
tasks:
- block:
- shell: 'ls /opt'
- shell: 'ls /testdir'
- shell: 'ls /c'
rescue:
- debug:
msg: 'I caught an error'
加入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"
block中有多个任务,rescue中也有多个任务,上例中故意执行"/bin/false"命令,模拟任务出错的情况,当 block中的’/bin/false’执行后,其后的debug任务将不会被执行,因为’/bin/false’模拟出错,出错后直接执行rescue 中的任务,在执行rescue中的任务时,会先输出 ‘I caught an error’,然后又在rescue中使用’/bin/false’模拟出错的情况,出错后之后的debug任务不会被执行,直接执行always中的任 务,always中的任务一定会被执行,无论block中的任务是否出错。
————Blueicex 2020/3/28 11:13 blueice1980@126.com