ansible语句详解
一、when判断
就是符合条件的,就可以执行任务
when里面,默认是识别变量名的,不需要使用{{}}来引用变量,但是如果是值的就需要双引号或者单引号
when是判断模块的,与模块对齐即可
when: "'test' in group_names" # test是值,需要引号,groups_names是魔法变量,不需要引号,when会自动的识别
1、判断的表达式(非常的多)
-
== 判断2边是否相等,比较字符串和数字
-
!= 判断2边是否不一致,不一致则为真
-
>= 判断左边是否大于等于右边
-
<= 判断左边是否小于等于右边
-
> 判断左边是否大于右边
-
< 判断左边是否小于右边
2、逻辑运算符
-
and 逻辑与,2边都为真则返回为真
-
or 逻辑或,只有一边为真,则返回为真
-
not 逻辑否 对结果取反,为真,则结果为假,在表达式的前面
-
() 当一组的表达式组合在一起时,看成一个整体
when: not inventory_hostname == "node1" # 不是node1主机执行任务
3、根据rc的返回值
通过注册变量来获取模块的返回值,register
- shell: ls /etc/passwd
register: get_status
- debug:
msg: "rc is 0"
when: get_status.rc == 0 # 返回结果为0,就执行
- debug:
msg: "rc is not 0"
when: get_status.rc != 0
4、通过判断路径是否存在
-
file 判断该路径是否为一个文件,是则为真
-
directory 是否为一个目录
-
link 判断是否为软连接
-
mount 判断是否为挂载点
-
exists 判断路径是否存在,存在则为真
vars:
file: /etc/passwd
- debug:
mgs: exist
when: "file is exists"
5、通过判断tasks任务的执行结果
-
还是通过注册变量实现的
-
changed 发生了改变
-
succeeded 任务执行成功了
-
failed 任务失败了
-
skipped 任务跳过,注意一个错误使用了ignore_errors,虽然忽略了这个错误,跳过了,但是这个任务是执行失败的,并没有跳过
- hosts: node
tasks:
- shell: ls /etc/passwdqqq
register: get_status # 保存结果到变量
ignore_errors: yes
- debug:
var: get_status
when: get_status is skip # 判断结果的状态
6、通过对变量进行判断
通过判断变量是否定义了来执行语句
# 变量定义了,但是没有赋值,仍然是定义过的
[devops@master when]$ cat 7.yml
- hosts: node
vars:
rhel: # 没有给这个变量赋值
tasks:
- debug:
msg: is none
when: rhel is defined
7、通过字符串进行判断大小写字母
lower 判断小写字母
upper 判断大写字母
[devops@master when]$ cat 15.yml
- hosts: node1
vars:
rhel: qqq
tasks:
- debug:
msg: lower
when: rhel is lower
# 输出信息
TASK [debug] ***************************************************************************
ok: [node1] => {
"msg": "lower"
}
8、通过数字来进行判断
-
even 判断数值是否为偶数,是则为真
-
odd 判断数值是否为奇数,是则为真
-
divisibleby(num)判断是否可以整除指定的数值,是则为真
[root@controller mnt]# cat f12.yml
- hosts: node1
vars:
rhel: 10
tasks:
- debug:
msg: oushu
when: rhel is divisibleby(2)
9、通过判断是否是子集或者父集,in的判断
-
in 判断是否存在
-
not in 不存在,判断不存在的
# 判断ens160是否存在这个接口上
[devops@master when]$ cat 8.yml
- hosts: node
tasks:
- debug:
msg: ens160 exists
when: "'ens160' in ansible_interfaces"
TASK [debug] ***************************************************************************
ok: [node1] => {
"msg": "ens160 exists"
}
ok: [master] => {
"msg": "ens160 exists"
}
二、其他关键字
1、block关键字
-
如果有多个模块且判断的条件都是一样的,就可以使用block,将模块都放在一个块里面,直接对块进行判断
-
判断成功执行,否则不执行
[devops@master when]$ cat 9.yml
- hosts: node
tasks:
- block:
- debug:
msg: block1
- debug:
msg: block2
when: ansible_hostname == 'node1'
TASK [debug] ***************************************************************************
ok: [node1] => {
"msg": "block2"
}
skipping: [master]
2、rescue关键字
-
如果block包含的模块出现了错误,就不执行,执行rescue关键字模块的内容
-
会继续执行后面的所有任务,不会停止任务,直到结束所有任务
[devops@master when]$ cat 9.yml
- hosts: node
tasks:
- block:
- debug: # 执行
msg: block1
- debug: # 执行
msg: block2
- shell: ls /etc/passwd111 # 报错,执行rescue块下的内容
when: ansible_hostname == 'node1'
rescue:
- debug:
msg: tasks is error
# 有rescue这个关键字,就会跳过错误任务,继续执行后面的所有任务,不会停止
- shell: ls /etc/passwd
fatal: [node1]: FAILED!
TASK [debug] **************************************************************************
ok: [node1] => {
"msg": "tasks is error"
}
3、always关键字
不管block中是否错误,都会继续执行关键字下面的模块内容
[devops@master when]$ cat 9.yml
- hosts: node
tasks:
- block:
- debug:
msg: block1
- debug:
msg: block2
- shell: ls /etc/passwd111
when: ansible_hostname == 'node1'
rescue:
- debug:
msg: tasks is error
always: # 总会执行
- debug:
msg: is always
4、fail和fail_when
-
fail终止剧本,如果报错的话,后面就不需要执行
-
就是如果当镜像都没有挂载的话,那么就不需要执行后面的所有任务了,没有一意义,直接跳过所有的即可
-
不能在block中使用
-
fail是一个模块,就是符合条件的话,就主动终止剧本,后面的内容不会继续执行
- name: 检查操作系统必须是 CentOS
ansible.builtin.fail:
msg: "本剧本只支持 CentOS,当前系统: {{ ansible_distribution }}"
when: ansible_distribution != "CentOS"
- name: 后面的任务只有系统是 CentOS 才会执行
ansible.builtin.debug:
msg: "系统检查通过,继续执行..."
-
fail_when 属于一个关键字
-
默认情况下,ansible看rc返回值,rc=0表示成功
-
但是fail_when 会覆盖默认规则,条件为真,任务标记失败
-
条件为假,任务标记为真
-
只是重新定义任务的状态,任务会继续执行的
-
- name: 检查应用状态(自定义失败)
ansible.builtin.command: /usr/bin/check_app.sh
register: app_result
# 定义:只要输出里有 ERROR,就算任务失败
failed_when: "'ERROR' in app_result.stdout"
- name: 对比两个文件(diff 特例)
ansible.builtin.command: diff file1 file2
register: diff_result
# diff:
# rc=0 → 相同(我们认为失败)
# rc=1 → 不同(正常)
# rc≥2 → 真错误(失败)
failed_when: diff_result.rc == 0 or diff_result.rc >= 2
三、循环语句
1、with_items
- item变量就是每次遍历(循环)所得到的值
[root@master test]# cat loop.yml
- hosts: node1
vars:
users:
- zhang
- wang
- li
tasks:
- debug:
msg: "{{item}}"
with_items: "{{users}}"
# 循环输出三次
另外一种写法
with_items:
- zhang
- wang
- li
2、with_dict
主要就是循环字典的
item.key 或者 item.value 获取value的值
只有item的话,key和value就都有
[devops@master when]$ cat 13.yml
- hosts: node1
vars:
users:
q1:
uid: 2022
name: zhang
q2:
uid: 2023
name: li
tasks:
- 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: node1
vars:
users:
q1:
uid: 2022
name: zhang
q2:
uid: 2023
name: li
tasks:
- 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: node1
vars:
users:
q1:
uid: 2022
name: zhang
q2:
uid: 2023
name: li
tasks:
- 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
# 遍历一个列表
[devops@master when]$ cat 13.yml
- hosts: node1
vars:
users:
- zhang
- wang
- li
tasks:
- debug:
msg: "{{item}}"
loop: "{{users}}"
# 或者其他的写法
loop:
- zhang
- wang
- lisi
TASK [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: node1
vars:
users:
q1:
uid: 2022
name: zhang
q2:
uid: 2023
name: li
tasks:
- 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: node1
vars:
rhel: "123"
tasks:
- user:
name: ppp
password: "{{rhel|password_hash('sha512')}}" # 直接进行加密,前面的密码必须是一个变量,系统设定的

浙公网安备 33010602011771号