when判断
-
就是符合条件的话,就可以执行这个模块的内容了
-
默认的when判断,识别变量名,不需要{{}}来引用变量,但是如果是值的话,就需要双引号或者单引号才行
vars:name: rhel9when: name # 不需要引号when: "'test' in group_names" # 值的话就需要单引号
-
判断的话,也是有一个返回值的
-
when 是判断模块的,因此的话,与模块对齐即可
1、判断的表达式
1、比较运算符
-
== 比较2边是否相等,比较字符串和数字
-
!= 2边是否一致,不一致则为真
-
>= 比较大小,左边大于为真
-
<= 右边大于为真
-
> 左边大于为真
-
< 右边大于为真
[devops@master when]$ cat 1.yml
- hosts: nodetasks:- debug:var: ansible_all_ipv4_addresses # 可以直接使用事实变量,系统自带的when: ansible_hostname == "master" # 主机为master执行任务,其他主机不执行# 输出结果为
TASK [debug] *************************************************************************
skipping: [node1]
ok: [master] => {"ansible_all_ipv4_addresses": ["192.168.50.10"]
}
2、逻辑运算符
-
and 逻辑与,2边都为真,则返回为真
-
or 逻辑或,只有一个为真,则返回为真
-
not 逻辑或,对结果取反,真为假,假为真,位置在表达式前面
-
() 当一组的表达式组合在一起后,看成一个整体
# and使用
[devops@master when]$ cat 2.yml
- hosts: nodetasks:- debug:msg: this is rhel 9when: ansible_distribution_version == "9.0" and ansible_distribution == "RedHat"# or 用法
# 可以直接使用ansible_ens160.ipv4.address
[devops@master when]$ cat 3.yml
- hosts: nodetasks:- debug:msg: this is orwhen: inventory_hostname == "node1" or ansible_ens160.ipv4.address == '192.168.50.10'# not用法[devops@master when]$ cat 3.yml
- hosts: nodetasks:- debug:msg: this is notwhen: not inventory_hostname == "node1" # 不是node1主机的执行任务TASK [debug] *************************************************************************
skipping: [node1] # node1跳过了
ok: [master] => {"msg": "this is not"
}
3、根据rc的返回值
-
file,copy等模块没有rc返回值,设计模块的时候定义的
-
命令模块有rc的返回值
[devops@master when]$ cat 4.yml
- hosts: nodetasks:- shell: ls /etc/passwdqqregister: get_statusignore_errors: yes- debug:msg: rc is 0when: get_status.rc == 0 # 结果的rc为0,执行这个模块- debug:msg: rc is not 0when: get_status.rc != 0 # 结果的rc不为0,执行这个模块TASK [debug] *************************************************************************
skipping: [node1]
skipping: [master]TASK [debug] *************************************************************************
ok: [node1] => {"msg": "rc is not 0"
}
ok: [master] => {"msg": "rc is not 0"
}
4、通过条件判断路径是否存在
-
file 判断指定路径是否为一个文件,是文件则为真
-
directory 是否为目录
-
link 是否为软链接
-
mount 是否为挂载点
-
exists 判断路径是否存在,存在则为真
[devops@master when]$ cat 5.yml
- hosts: nodetasks:- debug:msg: existwhen: "'/etc/passwd' is exists"TASK [debug] *************************************************************************
ok: [node1] => {"msg": "exist"
}
ok: [master] => {"msg": "exist"
}[devops@master when]$ cat 5.yml
- hosts: nodevars:file: /etc/passwdtasks:- debug:msg: existwhen: "file is exists"
5、通过判断tasks任务的执行结果(是对整个task任务进行判断)
-
判断的是整个的任务的执行结果
-
就是执行剧本的时候,tasks左边的ok
-
changed 发生了改变
-
succeeded 任务执行成功了
-
failed 任务失败
-
skipped 任务跳过,注意一个错误的任务使用ignore_errors忽略了这个错误,虽然是跳过的,但是这个任务执行是失败的,并没有跳过(这个是本质),虽然外像是跳过的状态
- hosts: nodetasks:- shell: ls /etc/passwdqqqregister: get_statusignore_errors: yes- debug:var: get_statuswhen: get_status is skip# 执行结果
# 任务是跳过的
TASK [debug] *************************************************************************
skipping: [node1]
skipping: [master]
6、通过对变量进行判断
-
变量没有定义,是一个什么样的情况
-
defined 变量定义了返回真
-
undefined 变量没有定义,返回假
# 变量定义了,但是没有赋值,仍然是定义过的[devops@master when]$ cat 7.yml
- hosts: nodevars:rhel:tasks:- debug:msg: is nonewhen: rhel is defined
7、通过字符串进行判断大小写字母
8、通过数字来进行判断
9、通过判断是否是子集或者是父集,in的判断
-
in判断的是非常常用的,判断是否存在
-
判断磁盘名是否在ansible_device中
-
磁盘判断案例
# 判断ens160是否存在这个接口上
[devops@master when]$ cat 8.yml
- hosts: nodetasks:- debug:msg: ens160 existswhen: "'ens160' in ansible_interfaces"TASK [debug] ***************************************************************************
ok: [node1] => {"msg": "ens160 exists"
}
ok: [master] => {"msg": "ens160 exists"
}
10、判断对象是否是字符串或者数字
2、其他的关键字
1、block关键字
-
如果有多个模块,并且多写几个when的话,就会非常的麻烦
-
因此的话,使用这个block直接判断好几个模块,这样的话就非常的方便了
--sy 可以检测yaml的语法
[devops@master when]$ cat 9.yml
- hosts: nodetasks:- block:- debug:msg: block1- debug:msg: block2when: ansible_hostname == 'node1'TASK [debug] ***************************************************************************
ok: [node1] => {"msg": "block2"
}
skipping: [master]
2、rescue关键字
-
如果block包含的模块中出现了错误,就跳过这个错误,执行rescue这个关键字模块的内容
-
会继续执行后面的所有任务,不会停止任务,知道结束所有任务
[devops@master when]$ cat 9.yml
- hosts: nodetasks:- block:- debug:msg: block1- debug:msg: block2- shell: ls /etc/passwd111when: ansible_hostname == 'node1'rescue:- debug:msg: tasks is error# 有rescue这个关键字,就会跳过错误任务,继续执行后面的所有任务,不会停止- shell: ls /etc/passwdfatal: [node1]: FAILED! TASK [debug] **************************************************************************
ok: [node1] => {"msg": "tasks is error"
}
3、always关键字
- 不管block中是否错误,都会执行这个关键字下面的模块内容
[devops@master when]$ cat 9.yml
- hosts: nodetasks:- block:- debug:msg: block1- debug:msg: block2- shell: ls /etc/passwd111when: ansible_hostname == 'node1'rescue:- debug:msg: tasks is erroralways:- debug:msg: is always
4、fail和fail_when
-
fail终止剧本的执行,如果报错的话,后面就不需要执行了
-
就是如果当镜像都没有挂载的话,那么就不需要执行后面的所有任务了,没有一意义,直接跳过所有的即可
-
不能在block中用
[devops@master when]$ cat 10.yml
- hosts: nodetasks:- debug:msg: block1- debug:msg: block2- shell: ls /etc/passwd111register: get_status# ignore_errors: yesfailed_when: get_status.rc != 0- shell: ls /etc/passwd# 不要使用这个ignore_errors这个就是即使模块中有错误的,也会执行[devops@master when]$ cat 11.yml
- hosts: nodetasks:- debug:msg: block1- shell: ls /etc/passwd111register: get_statusignore_errors: yes- fail:msg: juben exist # 显示这个错误信息,后面的模块不执行when: get_status.rc != 0- shell: ls /etc/passwd
循环语句
1、with_item
-
这个item可不可以换成其他的呢,必须是item,系统定义的
-
只能是这个item变量吗
-
与模块进行对齐
-
item 就等于每一次循环得到的值
-
将列表和字典的信息都打印出来,看一下
#
[devops@master when]$ cat 12.yml
- hosts: nodevars:users:- zhang- wang- litasks:- debug:msg: "{{item}}"with_items: "{{users}}"# 输出结果
ok: [node1] => (item=zhang) => {"msg": "zhang"
}
ok: [node1] => (item=wang) => {"msg": "wang"
}
ok: [node1] => (item=li) => {"msg": "li"
}
ok: [master] => (item=zhang) => {"msg": "zhang"
}
ok: [master] => (item=wang) => {"msg": "wang"
}
ok: [master] => (item=li) => {"msg": "li"
}# 这样的写法也是对的
[devops@master when]$ cat 12.yml
- hosts: nodetasks:- debug:msg: "{{item}}"with_items:- zhang- wang- li
2、with_dict
-
循环的字典
-
先直接打印这个item字段,看一下输出结果即可
-
item.key或者item.value 有key和value
-
与模块的对齐
-
item.value.字段 获取这个value指定的值
[devops@master when]$ cat 13.yml
- hosts: node1vars:users:q1:uid: 2022name: zhangq2:uid: 2023name: litasks:- debug:msg: "{{item}}"with_dict: "{{users}}"# 输出结果
TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {"msg": {"key": "q1","value": {"name": "zhang","uid": 2022}}
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {"msg": {"key": "q2","value": {"name": "li","uid": 2023}}
}# 获取key
[devops@master when]$ cat 13.yml
- hosts: node1vars:users:q1:uid: 2022name: zhangq2:uid: 2023name: litasks:- debug:msg: "{{item.key}}"with_dict: "{{users}}"# 输出信息
TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {"msg": "q1"
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {"msg": "q2"
}[devops@master when]$ cat 13.yml
- hosts: node1vars:users:q1:uid: 2022name: zhangq2:uid: 2023name: litasks:- debug:msg: "{{item.value.name}}" # item.value.name 获取值with_dict: "{{users}}"# 获取了这个value值
TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {"msg": "zhang"
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {"msg": "li"
}
3、loop
-
最常用的,字典和列表都能进行循环
-
天生能循环列表
-
循环字典的话,就需要使用过滤器
-
dict2items,有的版本没有,因此需要安装更高的版本
-
rhel9安装2.9的版本,太低了,应该安装高的版本
-
常见的过滤器
-
password_hash('sha512'),识别成了一个变量
-
default
-
dict2items 字典的过滤器
-
[devops@master when]$ cat 13.yml
- hosts: node1vars:users:- zhang- wang- litasks:- debug:msg: "{{item}}"loop: "{{users}}"# 或者其他的写法loop:- zhang- wang- lisiTASK [debug] ***************************************************************************
ok: [node1] => (item=zhang) => {"msg": "zhang"
}
ok: [node1] => (item=wang) => {"msg": "wang"
}
ok: [node1] => (item=li) => {"msg": "li"
}
[devops@master when]$ cat 13.yml
- hosts: node1vars:users:q1:uid: 2022name: zhangq2:uid: 2023name: litasks:- debug:msg: "{{item.value.name}}"loop: "{{users|dict2items}}" # 过滤器,可以使用字典TASK [debug] ***************************************************************************
ok: [node1] => (item={'key': 'q1', 'value': {'uid': 2022, 'name': 'zhang'}}) => {"msg": "zhang"
}
ok: [node1] => (item={'key': 'q2', 'value': {'uid': 2023, 'name': 'li'}}) => {"msg": "li"
}
# 密码过滤器
[devops@master when]$ cat 14.yml
- hosts: node1vars:rhel: "123"tasks:- user:name: ppppassword: "{{rhel|password_hash('sha512')}}" # 直接进行加密,前面的密码必须是一个变量,系统设定的
总结
-
when 里面的变量需不需要引号
-
如果是系统变量,或者vars其他定义好的变量,不需要双引号,可以直接使用,when是识别的
-
如果是值的话,就需要 "'/etc/passwd is exists'" 双引号,然后单引号括值即可