转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。
在《Ansible-playbook的逻辑控制 ①》中,梳理了逻辑控制when的使用场景,本文则继续梳理学习loop与block块的使用场景。
when:条件判断语句,类似于shell中的if;
loop:循环语句,类似于 shell中的while;
block:把几个任务组成一个代码块,以便于针对一组操作的异常进行处理等操作。
SRE成长记,公众号:SRE成长记Ansible-playbook的逻辑控制 ①
Loop用法
1. 简单的标准循环
在Ansible-playbook的逻辑控制 ①中,when与with_items共用判断数字的例子还可以这样写:
[root@test101 ansible-test]# cat loop1.yaml
---
- hosts: test
gather_facts: no
tasks:
- name: test of loop
debug:
msg: item is {{ item }}
##with_items: [ 0, 3, 5, 8, 10, 26 ] #原写法
#loop: [ 0, 3, 5, 8, 10, 26 ] #写法一
loop: #写法二
- 0
- 3
- 5
- 8
- 10
- 26
when: item > 6
[root@test101 ansible-test]#
使用举例—使用loop批量创建一组文件:
[root@test101 ansible-test]# cat loop2.yaml
---
- hosts: test
gather_facts: no
tasks:
- name: test of loop
file: path=/tmp/sre{{ item }}.txt state=touch
#loop: [ 1, 2, 3 ] #写法一
loop: #写法二
- 1
- 2
- 3
[root@test101 ansible-test]#
执行结果:
如果文件名的后缀、文件名都不统一,可以将要创建的文件列举出来,这种场景适用于创建少量文件,如果几十、上千百,就不适用了:
[root@test101 ansible-test]# cat loop3.yaml
---
- hosts: test
gather_facts: no
tasks:
- name: test of loop
file: path=/tmp/sre{{ item }} state=touch
#loop: [ sre.txt, test.yaml, file.sh ] #写法一
loop: #写法二
- sre.txt
- test.yaml
- file.sh
[root@test101 ansible-test]#
执行结果:
2. 与变量一起使用
如果在变量文件或vars区域定义了一组列表变量,也可以使用loop来循环变量。
如上面的创建文件的例子可以这样写:
[root@test101 ansible-test]# cat loop4.yaml
---
- hosts: test
gather_facts: no
vars:
files: [ "sre.txt", "test.yaml", "file.sh" ]
tasks:
- name: test of loop
file: path=/tmp/sre{{ item }} state=touch
#with_items: "{{files}}" #写法一
loop: "{{files}}" #写法二
[root@test101 ansible-test]#
执行结果:
3. 嵌套循环
loop循环也可以嵌套,可以用[]和 . 访问内层和外层的循环。
例如:
[root@test101 ansible-test]# cat loop5.yaml
---
- hosts: test
gather_facts: no
tasks:
- name: test of loop
debug:
#msg: "my hostname is {{ item[0] }},and my ip is {{ item[1] }}" #写法一
msg: "my hostname is {{ item.0 }},and my ip is {{ item.1 }}" #写法二
with_nested:
- [ 'test102', 'test103' ]
- [ '10.0.0.102', '10.0.0.103' ]
tags:
loops
[root@test101 ansible-test]#
执行结果:
4. 哈希表循环
除了嵌套循环,还可以对hash表进行循环。
例如,使用循环批量创建2个用户并执行需要所在的组:
[root@test101 ansible-test]# cat loop6.yaml
---
- hosts: test
gather_facts: no
tasks:
- name: test of loop
user: name={{ item.name }} state=present groups={{ item.groups }}
#with_items:
loop:
- { name: 'sre1', groups: 'sre' } # group需要是已存在group
- { name: 'sre2', groups: 'root' }
[root@test101 ansible-test]#
执行结果:
再例如,打印一组服务器节点信息:
[root@test101 ansible-test]# cat loop7.yaml
---
- hosts: test
gather_facts: no
vars:
servers:
server102:
hostname: test102
ip: 10.0.0.102
server103:
hostname: test103
ip: 10.0.0.103
tasks:
- name: test of loop
debug:
msg: "servers {{ item.key }} is {{ item.value.hostname }} ({{ item.value.ip }})"
#with_dict: "{{ servers }}" #写法一
loop: "{{ lookup('dict',servers)}}" #写法二
[root@test101 ansible-test]#
执行结果:
5. 对文件列表使用循环
[root@test101 ansible-test]# cat loop8.yaml
---
- name: test of loop
hosts: test
gather_facts: false # We don't need to gather facts
tasks:
- name: Find .txt files in /tmp directory
find:
paths: /tmp
patterns: "*.txt"
register: txt_files
- name: show all .txt files
debug:
msg: "{{ item.path }}"
loop: "{{ txt_files.files }}"
when: txt_files.matched > 0
[root@test101 ansible-test]#
执行效果:
Block块
在ansible中,还可以使用"block"关键字将多个任务整合成一个"块",这个"块"将被当做一个整体。可以根据不同的条件,执行一段语句。
例如,通过block语句判断docker服务是否存在:
[root@test101 ansible-test]# cat block1.yaml
---
- name: test of block
hosts: test
become: yes # Ensure privilege escalation if required
tasks:
- name: Check if docker is installed
shell: systemctl is-active docker
register: service_status
ignore_errors: yes # Ignore errors if doker doesn't exist
- name: Stop docker if it's running
block:
- name: Stop the docker
systemd:
name: docker
state: stopped
when: service_status.rc == 0 # Only stop if docker is active
- name: Disable docker
systemd:
name: docker
enabled: no
when: service_status.rc == 0 # Only disable if docker was active
when: service_status.rc == 0 # Only execute block if docker is installed and running
[root@test101 ansible-test]#
执行效果:
(END)