ansible8:ansible循环

说明

  在使用ansible时,我们经常需要查看或者处理一些返回信息,这些返回信息多是呈现为列表的形式,当信息很多时不便于我们查看,这时候就需要用循环将列表的有序呈现出来,根据官网说明,ansible循环到目前为止分为仨版本,这里直接介绍第一种迁移到第三种的改变:

  1. ansible 2.5版本之前,循环通过”with_“开头的关键字实现。
  2. ansible 2.5版本,官方推荐使用“loop+lookup插件”(插件名对应with_后面的名字。)的方式来替代“with_”方式实现循环,但依然支持“with_”用法。比如with_flattened: "{{testvar}}"和loop: {{lookup('flattened',testvar)}}就是等同作用,flattened就是lookup插件。
  3. ansible 2.6版本,官方推荐使用"loop+filter"用法来替代之前的方式实现循环,但依然支持前面两种用法。

  我不想接受他的建议,算了,还是接受吧 -_-||>。

with_和loop循环

  1. with_items举例使用:批量创建文件。

    # with_方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1: 		
          - "/root/aaa"
          - "/root/bbb"
          - "/root/ccc"
      tasks:
      - name: create directory
        file: path={{item}} state=touch
        with_items: "{{var1}}"
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - "/root/aaa"
          - "/root/bbb"
          - "/root/ccc"
      tasks:
      - name: create directory
        file: path={{item}} state=directory
        loop: "{{ var1 | flatten }}"
    # 省事的写法,可以省去vars。我下面例子都注明vars便于理解。
    ---
    - hosts: ck-node1
      tasks:
      - name: create directory
        file: path={{item}} state=touch
        with_items: 
          - "/root/aaa"
          - "/root/bbb"
          - "/root/ccc"
    
  2. with_flattened:和with_items作用一致。

  3. with_list:会输出列表的整体内容,不会遍历列表。

    # with_方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - [1,2,3]
          - [aa,bb,cc]
      tasks:
      - debug:
          msg: "{{item}}"
        with_list: "{{var1}}"
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - [1,2,3]
          - [aa,bb,cc]
      tasks:
      - debug:
          msg: "{{item}}"
        loop: "{{var1}}"
    
  4. with_together:将两个列表对齐,合并输出。

    # with_方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - [1,2,3]
          - [aa,bb]
      tasks:
      - debug:
          msg: "{{item}}"
        with_together: "{{var1}}"
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - [1,2,3]
          - [aa,bb]
      tasks:
      - debug:
          msg: "{{item}}"
        loop: "{{var1[0] | zip_longest(var1[1]) | list}}"
    # with_together等同于loop+zip_logest+list。表示按最长的列表对齐,按最短列表对齐可以使用loop+zip+list
    
  5. with_indexed_items:打印出循环列表中每一项的索引。

    # with_方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - aa
          - [bb,cc]
          - [dd,[ee,ff]]
      tasks:
      - debug:
          msg: "{{item}}"
        with_indexed_items: "{{var1}}"
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - aa
          - [bb,cc]
          - [dd,[ee,ff]]
      tasks:
      - debug:
          msg: "{{var1_index}},{{item}}"
        loop: "{{var1 | flatten(levels=1)}}"	# 1代表之展开1层列表,2代表第2层列表。
        loop_control:
          index_var: var1_index
    # loop_control用于控制循环的行为,比如将循环获取到的元素索引放在指定的var1_index变量中。
    
  6. with_cartesian:笛卡尔积的方式组合列表,两两相组。

    # with_方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - [a,b,c]
          - [test1,test2]
      tasks:
      - debug:
          msg: "{{item}}"
        with_cartesian: "{{var1}}"
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      vars:
        var1:
          - [a,b,c]
          - [test1,test2]
      tasks:
      - debug:
          msg: "{{item}}"
        loop: "{{var1[0] | product(var1[1]) | list}}"
    
  7. with_sequence:按照顺序生成数字序列。

    举例1:
    # with_方式实现。
    ---
    - hosts: ck-node1
      tasks:
      - debug:
          msg: "{{item}}"
        with_sequence: start=1 end=5 stride=1	# 从1开始,到5结束,步长为1。此种写法等于count=5
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      tasks:
      - debug:
          msg: "{{item}}"
        loop: "{{range(1,5,1) | list}}"
    PS:步长省略时默认值为1,当end值小于start值时,步长不可省略。rangge函数的操作范围不包含结束,也就是不包含5。
    # 举例2:格式化功能。
      0 18:19:10 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat aaa.yaml
    ---
    - hosts: ck-node1
      tasks:
      - debug:
          msg: "{{item}}"
        with_sequence: start=1 end=5 stride=1 format="number is %0.2f"
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      tasks:
      - debug:
          msg: "{{'number is %0.2f' | format(item)}}"
        loop: "{{range(1,5,1) | list}}"
    
  8. with_dict:接收变量信息,并将变量的信息以字典的形式输出。

    # with_方式实现。
    ---
    - hosts: ck-node1
      vars:
        users:
          bob: male
          zoe: female
      tasks:
        - debug:
            msg: "{{item}}"
          with_dict: "{{users}}"
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      vars:
        users:
          bob: male
          zoe: female
      tasks:
      - debug:
          msg: "{{item.key}} is {{item.value}}"
        loop: "{{ users | dict2items }}"
    
  9. with_random_choice:从列表的多个值中随机返回一个值。

    # with_方式实现。
    ---
    - hosts: ck-node1
      tasks:
      - debug:
          msg: "{{item}}"
        with_random_choice: [1,aa,32,bb]
    --------------------------------------------------------------------------------------------------------
    # 使用random函数可以替代with_random_choice,由于random函数是随机取出列表中的一个值,并不涉及循环操作,所以并不用使用loop关键字。
    ---
    - hosts: ck-node1
      vars:
        var1: [1,aa,32,bb]
      tasks:
      - debug:
          msg: "{{var1 | random}}"
    
  10. with_subelements:结合变量的子单元处理数据,使用时需要指定一个子元素,该子元素必须是一个列表。

    # with_方式实现。
    ---
    - hosts: ck-node1
      vars:
        users:
        - name: bob
          gender: male
          hobby: ['swimming','running']
        - name: zoe
          gender: female
          hobby: ['music']
      tasks:
      - debug:
          msg: "{{item.0.name}}'s hobby is {{item.1}}"
        with_subelements:
          - "{{users}}"
          - hobby		# 指定子元素
    --------------------------------------------------------------------------------------------------------
    # 使用loop+filter方式实现。
    ---
    - hosts: ck-node1
      vars:
        users:
        - name: bob
          gender: male
          hobby: ['swimming','running']
        - name: zoe
          gender: female
          hobby: ['music']
      tasks:
      - debug:
          msg: "{{item.0.name}}'s hobby is {{item.1}}"
        loop: "{{users | subelements('hobby')}}"
    

loop_control

  在介绍with_indexed_items,已经初步接触loop_control,它用于控制循环的行为,比如上面的index_var选项可以在遍历列表时,将元素的索引写入对应的变量中,下面再介绍一些loop_control的其它选项。

  1. pause:用于设置每次循环的时间间隔,以秒为单位。

      0 19:31:05 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat test1.yaml
    ---
    - hosts: ck-node1
      tasks:
      - debug:
          msg: "{{item}}"
        loop: [aa,bb,cc]	# 写在下面也可以。
          #- aa
          #- bb
          #- cc
        loop_control:
          pause: 2
    
  2. label:简化输出结果,只输出label指定的标签。

      0 19:45:10 root@ck-ansible,172.16.2.9:/server/ops_ansible # cat test2.yaml
    ---
    - hosts: ck-node1
      vars:
        users:
          bob_info:
            name: bob
            sex: male
            tel: 17621886666
          zoe_info:
            name: zoe
            sex: female
            tel: 17621886667
      tasks:
      - debug:
          msg: "{{item.key}}"
        loop: "{{users | dict2items}}"
        loop_control:
          label: "{{item.key}}"
    
    1. loop_var:结合include在第10章节的第5例中讲解。


写作不易,转载请注明出处,谢谢~~

posted @ 2021-11-04 16:03  loosenc  阅读(926)  评论(0编辑  收藏  举报