在Ansible编写剧本的时候,我们往往遇到许多重复性的操作,比如安装各种软件包,在某个目录操作各种文件等等。通过利用循环,我们无需编写多个使用同一模块的任务。例如,他们不必编写五个任务来确保存在五个用户,而是只需编写一个任务来对含有五个用户的列表迭代,从而确保它们都存在。
Ansible支持使用loop关键字对一组项目迭代任务。可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。
循环可对一组项目进行迭代任务。使用loop关键字添加到任务中,将应对其迭代任务的项目列表取为值。循环变量item保存每个迭代过程中使用的值。可以理解为loop和item就是一配对。
---
- hosts: localhost
tasks:
- name: mkdir /home/student/abc
shell: mkdir /home/student/abc
- name: mkdir /home/student/cde
shell: mkdir /home/student/cde
# cat test.yml
---
- hosts: localhost
tasks:
- name: mkdir /home/student/ file
shell: "mkdir /home/student/{{ item }}"
loop:
- abc
- cde
明显使用一次shell模块,而不用使用二次就可以达到最终的需求。(突然感觉气血通畅,爽!)
(这种偏门点的招式,还是看看就好)
---
- hosts: localhost
vars:
dir_name:
- abc
- cde
tasks:
- name: mkdir /home/student/ file
shell: "mkdir /home/student/{{ item }}"
loop: "{{ dir_name }}"
loop列表可不以简单的值作为调用,而是使用散列或字典,这较为复杂一点的写法。
在以下示例中,列表中的每个项实际上是散列或字典。示例中的每个散列或字典具有两个键,即name和groups,当前item循环变量中每个键的值可以分别通过item.name和item.groups变量来检索。
---
- hosts: localhost
tasks:
- name: user loop test
user:
name: "{{ item.name }}"
state: present
group: "{{ item.group }}"
loop:
- name: chap
group: chap
- name: rebel
group: rebel
(还记得上文所说的loop和item配对吗?item.name其实就是loop.name,人家是比翼双飞,水影鸳鸾 >.<)
在Ansible2.5之前,大多数playbook使用不同的循环语法。提供了多个循环关键字,前缀为with_,后面跟Ansible查找插件的名称。这种循环语法在现有playbook中很常见,但在将来的某个时候可能会被弃用。
(看来招式还是需要定期更新才行,不过在人家还没有过时前,还是得先见招拆招。)
with_****items循环playbook演示:
---
- hosts: localhost
vars:
data:
- abc
- cde
- efg
tasks:
- name: with_item test
debug:
msg: "{{ item }}"
with_items: "{{ data }}"
register关键字也可以用来捕获循环任务的输出。以下代码片段显示了循环任务中register变量的结构:
[student@servera example]$ cat loop-register.yml
---
- hosts: localhost
tasks:
- name: register and loop
shell: "echo test {{ item }}"
loop:
- abc
- cde
register: results
- name: print result
debug:
var: results
[student@servera example]$ ansible-playbook loop-register.yml
PLAY [loop-register] *******************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [localhost]
TASK [register and loop] ***************************************************************
changed: [localhost] => (item=abc)
changed: [localhost] => (item=def)
TASK [print result] ********************************************************************
ok: [localhost] => {
"results": {
"changed": true,
"msg": "All items completed",
"results": [
{
"ansible_loop_var": "item",
"changed": true,
"cmd": "echo test abc",
"delta": "0:00:00.007471",
"end": "2021-12-09 23:47:00.084344",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "echo test abc",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"item": "abc",
"rc": 0,
"start": "2021-12-09 23:47:00.076873",
"stderr": "",
"stderr_lines": [],
"stdout": "test abc",
"stdout_lines": [
"test abc"
]
},
{
"ansible_loop_var": "item",
"changed": true,
"cmd": "echo test def",
"delta": "0:00:00.007672",
"end": "2021-12-09 23:47:00.259170",
"failed": false,
"invocation": {
"module_args": {
"_raw_params": "echo test def",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"item": "def",
"rc": 0,
"start": "2021-12-09 23:47:00.251498",
"stderr": "",
"stderr_lines": [],
"stdout": "test def",
"stdout_lines": [
"test def"
]
}
]
}
}
PLAY RECAP *****************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
更进一步的运用:
[student@servera example]$ cat loop-register.yml
---
- name: loop-register
hosts: localhost
tasks:
- name: register and loop
shell: "echo test {{ item }}"
loop:
- abc
- cde
register: results
- name: print results
debug:
msg: "Send out the message: {{ item.stdout }}"
loop: "{{ results['results'] }}"
# 此为运用散列或字典列表的形式,将results这注册变量所输出项中取results项中的值。
# loop: "{{ results.results }}"
# 还记得这个一样的写法吗~~不记得可参考https://blog.csdn.net/qq_41765918/article/details/121796046 章节中,新旧语法对比。
[student@servera example]$ ansible-playbook loop-register.yml
PLAY [loop-register] *******************************************************************
TASK [Gathering Facts] *****************************************************************
ok: [localhost]
TASK [register and loop] ***************************************************************
changed: [localhost] => (item=abc)
changed: [localhost] => (item=def)
TASK [print results] *******************************************************************
ok: [localhost] => (item={u'stderr_lines': [], u'ansible_loop_var': u'item', u'end': u'2021-12-09 23:41:27.978177', u'stderr': u'', u'stdout': u'test abc', u'changed': True, u'failed': False, u'delta': u'0:00:00.007256', u'cmd': u'echo test abc', u'item': u'abc', u'rc': 0, u'invocation': {u'module_args': {u'warn': True, u'executable': None, u'_uses_shell': True, u'strip_empty_ends': True, u'_raw_params': u'echo test abc', u'removes': None, u'argv': None, u'creates': None, u'chdir': None, u'stdin_add_newline': True, u'stdin': None}}, u'stdout_lines': [u'test abc'], u'start': u'2021-12-09 23:41:27.970921'}) => {
"msg": "Send out the message: test abc"
}
ok: [localhost] => (item={u'stderr_lines': [], u'ansible_loop_var': u'item', u'end': u'2021-12-09 23:41:28.148281', u'stderr': u'', u'stdout': u'test def', u'changed': True, u'failed': False, u'delta': u'0:00:00.007047', u'cmd': u'echo test def', u'item': u'def', u'rc': 0, u'invocation': {u'module_args': {u'warn': True, u'executable': None, u'_uses_shell': True, u'strip_empty_ends': True, u'_raw_params': u'echo test def', u'removes': None, u'argv': None, u'creates': None, u'chdir': None, u'stdin_add_newline': True, u'stdin': None}}, u'stdout_lines': [u'test def'], u'start': u'2021-12-09 23:41:28.141234'}) => {
"msg": "Send out the message: test def"
}
PLAY RECAP *****************************************************************************
localhost: ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
阅读量:1796
点赞量:0
收藏量:0