ansible 迭代with_item、with_list、with_dict、with_togther

发布时间 2023-03-29 17:03:59作者: 橘子飞飞

ansible 迭代介绍:

执行一些重复性操作,比如指安装软件包,批量创建用户,操作某个目录下的所有文件等;

 

基本的循环:

1、列表字符串等的循环;

如:

---        
- name: with item test hosts: all tasks: - name: item 1 shell: echo {{item}} with_items: - nginx - vim - iperf # [nginx,vim,iperf] # 写法2 # {nginx,vim,iperf} # 写法3

2、字典的循环

如:

---
        - name: with item test
          hosts: all
          tasks:
          - name: item 2
            debug:
              msg: "{{item.name}},{{item.age}}"
              with_items:
                - { name: zhangsan,age: 10 }
                - { name: lisi,age: 20 }
              tags: item2

3、外部yml文件中定义的变量引入循环

定义变量的文件define_var.yml

---
        apache:
          protocol: http
          port: [80,8080]
          timeout: 20

测试在with_item 中引入:

---
        - name: with item test
          hosts: all
          vars_files: ./define_var.yml
          tasks:
            - name: item3 var_file
              debug:
                msg: "{{item}}\n,{{item.port}}\n,{{item.port[0]}}"
              with_items:
                - "{{apache}}"
              tags: tag3

执行结果:

root@master:/home/user1# ansible-playbook -i ansible_host test_with_items.yml -t tag3

            PLAY [with item test] ********************************************************************************

            TASK [Gathering Facts] *******************************************************************************
            ok: [192.168.108.23]
            ok: [192.168.108.22]

            TASK [item3 var_file] ********************************************************************************
            ok: [192.168.108.22] => (item={'protocol': 'http', 'port': [80, 8080], 'timeout': 20}) => {}

            MSG:

            {'protocol': 'http', 'port': [80, 8080], 'timeout': 20}
            ,[80, 8080]
            ,80

4、with_items、 with_list

with_items 中的列表嵌套列表会打印出所有的最小个体;
如:

 ---
          - name: with item test
            hosts: hostA
            tasks:
              - name: items contains items
            debug:
              msg: "all item value:{{item}}"
            with_items:
              - ['1','2']
              - [a,b]
            tags: tag4

执行结果:

root@master:/home/user1# ansible-playbook -i ansible_host test_with_items.yml -t tag4

        PLAY [with item test] *************************************************************************************

        TASK [Gathering Facts] ************************************************************************************
        ok: [192.168.108.22]

        TASK [items contains items] *******************************************************************************
        ok: [192.168.108.22] => (item=1) => {}

        MSG:
        all item value:1
        ok: [192.168.108.22] => (item=2) => {}

        MSG:
        all item value:2
        ok: [192.168.108.22] => (item=a) => {}

        MSG:
        all item value:a
        ok: [192.168.108.22] => (item=b) => {}

        MSG:
        all item value:b

测试结果显示为完全循环了列表中的任意一个元素;
with_list:
如果不需要循环任意一个元素,如:想得到的结果为两个单独的大集合,那么请使用后with_list,使用方法与with_item 完全一致;
即得到的结果为:
all item value:['1', '2']
all item value:['a', 'b']

5、with_list与with_together

with_list 不介绍,查看with_items即可;
with_togther可以将两个列表中的元素”对齐合并”;
如:
给定的两个列表元素为:
-['1','2']
-['a','b']
在执行完with_togther后,会组成新的列表,如果列表长度不一致的话,会补充为None:
['1',u'a']
['2',u'b']

6、with_dict

"with_dict"的使用场景应该与"字典"有关,可理解为获取字典中的键值信息;
如:
定义好的外部变量文件define_dict_var.yml:

---
        - info:
            zhangsan:
              age: 20
            lisi:
              age: 40

测试中定义的测试文件test_dict.yml:

---
        - hosts: hostA
          vars_files: ./define_dict_var.yml
          tasks:
            - name: "测试dict 1"
              debug:
                msg: "{{item}}"
              with_dict:
                - "{{info}}"
              tags: tag1

执行测试脚本:

root@master:/home/user1# ansible-playbook -i ansible_host test_dict.yml -t tag1

        PLAY [hostA] ********************************************************************************************************************
        TASK [Gathering Facts] **********************************************************************************************************
        ok: [192.168.108.22]
        TASK [测试dict 1] ***************************************************************************************************************
        ok: [192.168.108.22] => (item={'key': 'zhangsan', 'value': {'age': 20}}) => {}

        MSG:
        {'key': 'zhangsan', 'value': {'age': 20}}
        ok: [192.168.108.22] => (item={'key': 'lisi', 'value': {'age': 40}}) => {}

        MSG:
        {'key': 'lisi', 'value': {'age': 40}}

        PLAY RECAP **********************************************************************************************************************
        192.168.108.22             : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

由上面的测试结果看出: 键值对中的"键"被放入了"key"关键字中,键值对中的"值"被放入了"value"关键字中,所以,我们可以通过key关键字和value关键字
分别获取到字典中键值对的"键"和"值";
所以在获取实际值的时候,可以采用.key 或.value 来获取具体value 的值;
如:

---
        - hosts: hostA
          vars_files: ./define_dict_var.yml
          tasks:
            - name: "测试dict 2"
              debug:
                msg: "{{item.key}} {{item.value.age}}"
              with_dict: "{{info}}"
              tags: tag2