Ansible循环(loop)
有时您想重复执行多次任务。在计算机编程中,这称为循环。常见的Ansible循环包括使用文件模块更改多个文件和/或目录的所有权,使用用户模块创建多个用户以及重复轮询步骤直到达到特定结果。Ansible提供了两个用于创建循环的关键字:loop和with_
注意:目前ansible2.5中,我们习惯于用loop替代with_*
循环方式
简单遍历
重复的任务可以作为标准循环写在简单的字符串列表上。可以直接在任务中定义列表
被控机上有3个用户。想利用循环删除这 3个用户
[root@localhost ~]# id test1
uid=1001(test1) gid=1001(test1) groups=1001(test1)
[root@localhost ~]# id test2
uid=1002(test2) gid=1002(test2) groups=1002(test2),10(wheel)
[root@localhost ~]# id test3
uid=1003(test3) gid=1003(test3) groups=1003(test3),0(root)
[root@localhost project]# vim ceshi2.yml
---
- name: test
hosts: 192.168.190.134
tasks:
- name: delete user
user:
name: "{{ item }}" 调用循环变量。代表loop下面的循环体
state: absent
loop:
- test1 创建3个列表。用来代表循环体
- test2
- test3
changed: [192.168.190.134] => (item=test1)
changed: [192.168.190.134] => (item=test2)
changed: [192.168.190.134] => (item=test3)
......
同时也可以利用变量来作为循环体
[root@localhost project]# !vim
vim ceshi2.yml
---
- name: test
hosts: 192.168.190.134
vars:
test_name: 定义变量
- test1
- test2
- test3
tasks:
- name: delete user
user:
name: "{{ item }}"
state: present
loop: "{{ test_name }}" 调用变量
changed: [192.168.190.134] => (item=test1)
changed: [192.168.190.134] => (item=test2)
changed: [192.168.190.134] => (item=test3)
哈希表遍历
[root@localhost project]# !vim
vim ceshi2.yml
---
- name: test
hosts: 192.168.190.134
tasks:
- name: delete user
user:
name: "{{ item.name }}" 引用哈希表中子项
groups: "{{ item.groups }}"
state: present
loop:
- name: test1
groups: root
- name: test2
groups: test1
changed: [192.168.190.134] => (item={'name': 'test1', 'groups': 'root'})
changed: [192.168.190.134] => (item={'name': 'test2', 'groups': 'test1'})
注册变量与loop
---
- name: test
hosts: 192.168.190.134
gather_facts: no
tasks:
- name: delete user
shell: echo '{{ item }}'
loop:
- one
- two
register: result
- name: print
debug:
msg: "{{ result.results }}"
ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"ansible_loop_var": "item",
"changed": true,
"cmd": "echo 'one'",
"delta": "0:00:00.003743",
"end": "2020-09-06 11:27:13.127451",
"failed": false,
"invocation": {
......
Ansible条件判断(when)
条件判断:
when的值是一个条件表达式,如果条件判断成立,这个task就执行,如果判断不成立,则task不执行
常见判断符号
符号 | 说明 |
---|---|
== | 比较两个对象是否相等,相等为真 |
=! | 比较两个对象是否不等,不等为真 |
|比较两个值的大小,如果左边的值大于右边的值,则为真|
<|比较两个值的大小,如果左边的值小于右边的值,则为真|
=|比较两个值的大小,如果左边的值大于右边的值或左右相等,则为真|
<=|比较两个值的大小,如果左边的值小于右边的值或左右相等,则为真|
and|逻辑与,当左边与右边同时为真,则返回真|
or|逻辑或,当左边与右边有任意一个为真,则返回真|
not|取反|
is defined| 变量被定义且存在
is not defined| 变量不存在
简单判断
例:
- 被控机必须是RedHat系统
- 被控及版本号必须为8.1
[root@localhost project]# vim ceshi1.yml
---
- hosts: test_group
tasks:
- name: when
shell: echo 'hellp world'
when:
- ansible_facts.distribution == 'RedHat'
- ansible_facts.distribution_version == '8.1'
register: result
- debug:
var: result.stdout_lines
changed: [192.168.190.134]
changed: [192.168.190.133]
ok: [192.168.190.133] => {
"result.stdout_lines": [
"hellp world" 两台主机成功打印
]
}
ok: [192.168.190.134] => {
"result.stdout_lines": [
"hellp world"
]
}
组合判断
when 后加>,可以多行编辑
---
- hosts: test_group
tasks:
- name: when
shell: echo 'hellp world'
when: >
(ansible_facts.distribution == 'RedHat' and ansible_facts.distribution_version == '8.1')
or
(ansible_facts.distribution == 'CentOS' and ansible_facts.distribution_version == '7.1')
register: result
- debug:
var: result.stdout_lines
示例
删除test1用户,如果change值为true则证明成功执行,否则失败。且需要打印信息
注意:ignore_errors"表示即使当前task执行报错,ansible也会忽略这个错误,继续执行playbook
---
- name: 测试
hosts: test_group
tasks:
- name: delete user test1
user:
name: test1
state: absent
register: result
ignore_errors: yes 执行错误,play继续。
- debug:
msg: "命令运行成功"
when:
result.changed == True
- debug:
msg: "命令运行失败"
when:
result.changed != True
134主机上有test1,但是133主机上没有test1,所以134执行成功,但是133执行失败。
TASK [debug] *******************************************************************************************
skipping: [192.168.190.133]
ok: [192.168.190.134] => {
"msg": "命令运行成功"
}
TASK [debug] *******************************************************************************************
ok: [192.168.190.133] => {
"msg": "命令运行失败"
}
skipping: [192.168.190.134]