Ansible-playbook的逻辑控制 ②

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。


《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)

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值