任务控制
使用循环迭代任务
通过使用循环,我们无需编写多个使用同一模块的任务。例如,他们不必编写五个任务来确保存在五个用户,而是只需编写一个任务来对含有五个用户的列表迭代,从而确保它们都存在。
Ansible支持使用loop关键字对一组项目迭代任务。可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。
简单循环
简单循环对一组项目迭代任务。loop关键字添加到任务中,将应对其迭代任务的项目列表取为值。循环变量item保存每个迭代过程中使用的值。
比较:
创建三个用户:
[root@localhost ansible]# cat vars/user.yml
---
- name: create user
hosts: "*"
gather_facts: no
tasks:
- name: create three user
user:
name: aaa
state: present
- name: create harry
user:
name: bbb
state: present
- name: create jarry
user:
name: ccc
state: present
创建三个用户可以重新编写为使用一个简单循环:
---
- name: create user
hosts: "*"
tasks:
- name: create user three
user:
name: "{
{ item }}"
state: present
loop:
- aaa
- bbb
- ccc
可以通过一个变量提供loop所使用的列表。
---
- name: create user
hosts: "*"
vars:
users_1:
- aa
- bb
- cc
tasks:
- name: create user three
user:
name: "{
{ item }}"
state: present
loop: "{
{ users_1 }}"
循环散列或字典列表
loop列表不需要是简单值列表。在以下示例中,列表中的每个项实际上是散列或字典。示例中的每个散列或字典具有两个键,即name和groups,当前item循环变量中每个键的值可以分别通过item.name和item.groups变量来检索。
---
- name: create user
hosts: "*"
tasks:
- name: create user three
user:
name: "{
{ item.name }}"
state: present
groups: "{
{ item.groups }}"
loop:
- name: abc
groups: harry
- name: cba
groups: tom
较早样式的循环关键字
在Ansible2.5之前,大多数playbook使用不同的循环语法。提供了多个循环关键字,前缀为whth_,后面跟Ansible查找插件的名称。这种循环语法在现有playbook中很常见,但在将来的某个时候可能会被弃用。
较早样式的Ansible循环
循环关键字 | 描述 |
---|---|
with_items | 行为与简单列表的loop关键字相同,例如字符串列表或散列/字典列表。 但与loop不同的是,如果为with_items提供了列表的列表, 它们将被扁平化为单级列表。循环变量item保存每次迭代过程中使用的列表项。 |
with_file | 此关键字需要控制节点文件名列表。循环变量item在每次迭代过程中保存文件列表中相应文件的内容。 |
with_sequence | 此关键字不需要列表,而是需要参数来根据数字序列生成值列表。 循环变量item在每次迭代过程中保存生成的序列中的一个生成项的值。 |
playbook中的with_items的示例如下所示:
---
- name: create user
hosts: "*"
vars:
qwq:
- aaaa1
- aaaa2
- aaaa3
tasks:
- name: create user three
user:
name: "{
{ item }}"
state: present
with_items: "{
{ qwq }}"
从Ansible2.5开始,建议使用loop关键字编写循环。
将Register变量与Loop一起使用
register关键字也可以捕获循环任务的输出。以下代码片段显示了循环任务中register变量的结构:
[root@localhost ansible]# cat user/user.yml
---
- name: user
hosts: "*"
tasks:
- name: test
command: "echo 'hollo {
{ item }},aaa'"
loop:
- aaa
- bbb
- ccc
register: result
- debug:
var: result
[root@localhost ansible]# ansible-playbook user/user.yml
PLAY [user] ***********************************************************************
TASK [Gathering Facts] ************************************************************
ok: [192.168.100.42]
TASK [test] ***********************************************************************
changed: [192.168.100.42] => (item=aaa)
changed: [192.168.100.42] => (item=bbb)
changed: [192.168.100.42] => (item=ccc)
TASK [debug] ****
.....
有条件地运行任务
Ansible可使用conditionals在符合特定条件时执行任务或play。例如,可以利用一个条件在Ansible安 装或配置服务前确定受管主机上的可用内存。
我们可以利用条件来区分不同的受管主机,并根据它们所符合的条件来分配功能角色。Playbook变量、注册的变量和Ansible事实都可通过条件来进行测试。可以使用比较字符串、数字数据和布尔值的运算符。
以下场景说明了在Ansible中使用条件的情况:
- 可以在变量中定义硬限制(如min_memory)并将它与受管主机上的可用内存进行比较。
- Ansible可以捕获并评估命令的输出,以确定某一任务在执行进一步操作前是否已经完成。例如,如果某一程序失败,则将跳过批处理。
- 可以利用Ansible事实来确定受管主机网络配置,并决定要发送的模板文件(如,网络绑定或中继)。
- 可以评估CPU的数量,来确定如何正确调节某一Web服务器。
将注册的变量与预定义的变量进行比较,以确定服务是否已更改。例如,测试服务配置文件的MD5检验以和查看服务是否已更改。
条件任务语法
when语句用于有条件地运行任务。它取要测试的条件为值。如果条件满足,则运行任务。如果条件不满足,则跳过任务。
可以测试的一个最简单条件是某一布尔变量是True还是False。以下示例中的when语句导致任务仅在为True时运行:
[root@localhost ansible]# cat user/user.yml
---
- name: user
hosts: "*"
vars:
implement: true
tasks:
- name: test
command: "echo 'hollo {
{ item }},aaa'"
loop:
- aaa
- bbb
- ccc
when: implement
[root@localhost ansible]# ansible-playbook user/user.yml
PLAY [user] ***********************************************************************
TASK [Gathering Facts] ************************************************************
ok: [192.168.100.42]
TASK [test] ***********************************************************************
changed: [192.168.100.42] => (item=aaa)
changed: [192.168.100.42] => (item=bbb)
changed: [192.168.100.42] => (item=ccc)
PLAY RECAP ************************************************************************
192.168.100.42 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@localhost ansible]#
下表显示了在处理条件时可使用的一些运算:
示例条件
操作 | 示例 |
---|---|
等于(值为字符串) | ansible_machine == “x86_64” |
等于(值为数字) | max_memory == 512 |