已归录
简单的 loop 循环(simple loops)
# cat demo.yml
---
- name: demo of simple loops
hosts: web
gather_facts: no
tasks:
- name: services are running
service:
name: "{{ item }}"
state: started
loop:
- sshd
- crond
loop 使用的 list 也可以由变量提供
# cat demo.yml
---
- name: demo of simple loops
hosts: web
gather_facts: no
vars:
services_names:
- sshd
- crond
tasks:
- name: services are running
service:
name: "{{ item }}"
state: started
loop:
"{{ services_names }}"
loop 列表可以是字典(loops over a list of hashes or dictionaries)
# cat demo.yml
---
- name: demo of loops
hosts: web
gather_facts: no
tasks:
- name: services are running
service:
name: "{{ item.name }}"
state: "{{ item.state }}"
loop:
- name: sshd
state: started
- name: crond
state: started
这儿 loop 的另一种写法是:
loop:
- { name: "sshd", state: "started" }
- { name: "crond", state: "started" }
loop 使用的字典也可以由变量提供(教材未提)
---
- hosts: web
vars:
services:
service1:
name: sshd
state: started
service2:
name: crond
state: started
tasks:
- name: services are running
service:
name: "{{ item.value.name }}"
state: "{{ item.value.state }}"
loop: "{{ services|dict2items }}"
以前老版本不是用的 loop 关键字,而是 with_items 关键字,用法一样。从 Ansible 2.5 开始,推荐使用 loop。
loop 与 register 结合使用
# cat demo.yml
---
- hosts: web
vars:
services:
service1:
name: sshd
state: started
service2:
name: crond
state: started
tasks:
- name: services are running
shell: systemctl is-active "{{ item.value.name }}"
loop: "{{ services|dict2items }}"
register: cy_results
ignore_errors: yes
- name: show value of var
debug:
var: cy_results
注意两点:
- 一定要有 ignore_errors: yes,否则,如果服务没有运行将报错,就不能到 debug 显示注册变量的值
- 不用担心变量会被 loop 覆盖,它会把多次循环的结果都记录在注册变量['results']中(打印显示一下就明白了)
在该例中,如果想取 sshd 服务的状态:cy_results['results'][0]['rc'] 或者 cy_results['results'][0]['stdout_lines'][0]
现在,修改一下剧本,如果服务不是 active,则启动它:
# cat demo.yml
---
- hosts: web
vars:
services:
service1:
name: sshd
state: started
service2:
name: crond
state: started
tasks:
- name: services are running
shell: systemctl is-active "{{ item.value.name }}"
loop: "{{ services|dict2items }}"
register: cy_results
ignore_errors: yes
下面的取值感觉很复杂,其实很简单,在上面的输出中一层一层往下找就行了:
- name: start service if not started
service:
name: "{{ item.item.value.name }}"
state: started
when: item.rc != 0
loop: "{{ cy_results['results'] }}"