Ansible 循环

Ansible循环的代码展示
Ansible 循环
一、简单介绍
ansible2.5之前,大多数人使”with_XXX”类型的关键字来操作循环,但是从2.6版本开始,官方推荐是”loop”关键字代替” with_XXX”
1.我们先看下一个小例子,使用loop关键字进行最简单的循环:
[root@localhost cycle]# cat cycle.1.yml
---
  -name: cycletest
   hosts: test
   gather_facts: no
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ item }}"
     loop:
       - test1
       - test2



结果:
[root@localhost cycle]# ansible-playbookcycle.1.yml

PLAY [cycle test]***************************************************************************************

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item=test1)=> {
   "msg": "test1"
}
ok: [192.168.15.10] => (item=test2)=> {
   "msg": "test2"
}

PLAY RECAP**********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle------------------------------------------------------------- 0.17s
Playbook finished: Mon Dec 24 17:57:252018, 1 total tasks.  0:00:00 elapsed.


实例中所以loop关键字,替换之前的with_XXX关键字,它们的效果是完全相同的。
2.我们可以使用loop关键字和dict插件代替”with_dict”关键字,示例如下:
[root@localhost cycle]# cat cycle.2.yml
---
  -name: cycle test2
   hosts: test
   gather_facts: no
   vars:
     dicts:
       China: 1
       America: 2
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ item.key }} is no.{{ item.value }}"
     loop: "{{ lookup('dict',dicts) }}"


结果:
[root@localhost cycle]# ansible-playbookcycle.2.yml

PLAY [cycle test2]**************************************************************************************

TASK [debug cycle] **************************************************************************************
ok: [192.168.15.10] => (item={'key':u'America', 'value': 2}) => {
   "msg": "America is no.2"
}
ok: [192.168.15.10] => (item={'key':u'China', 'value': 1}) => {
   "msg": "China is no.1"
}

PLAY RECAP**********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle -------------------------------------------------------------0.18s

Playbook finished: Mon Dec 24 17:59:582018, 1 total tasks.  0:00:00 elapsed

示例已经在上一个例子中讲述,再次不在讲述
3.上个例子中使用”loop+lookup”的方式完成循环,而在2.6版本的官网中推荐使用”loop+filter”方式老代替”loop+loopup”的方式,什么意思呢我们来看个小例子,如下:
---
  -name: cycle test3
   hosts: test
   gather_facts: no
   vars:
     dicts:
       China: 1
       America: 2
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ item.key }} is no.{{ item.value }}"
     loop: "{{ dicts | dict2items }}"


结果:
[root@localhost cycle]# ansible-playbookcycle.3.yml

PLAY [cycle test3]**************************************************************************************

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item={'key':u'America', 'value': 2}) => {
   "msg": "America is no.2"
}
ok: [192.168.15.10] => (item={'key':u'China', 'value': 1}) => {
   "msg": "China is no.1"
}

PLAY RECAP **********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle------------------------------------------------------------- 0.18s

Playbook finished: Mon Dec 24 18:05:212018, 1 total tasks.  0:00:00 elapsed.

如上例所示,在使用loop关键字操作对于的字典变量users时,并没有借助dict插件,而是使用dict2items的过滤器。


二、具体示例
1.With_list
#loop可以替代with_list,当处理嵌套的列表时,列表不会被拉平
[root@localhost cycle]# cat cycle.4.yml
---
  -name: cycle test4
   hosts: test
   gather_facts: no
   vars:
     dicts:
       - A
       - B
       - [c,D]
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ item }}"
     loop: "{{ dicts }}"


结果:
[root@localhost cycle]# ansible-playbookcycle.4.yml

PLAY [cycle test4]**************************************************************************************

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item=A) => {
   "msg": "A"
}
ok: [192.168.15.10] => (item=B) => {
   "msg": "B"
}
ok: [192.168.15.10] => (item=[u'c',u'D']) => {
   "msg": [
       "c",
       "D"
}

PLAY RECAP **********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle------------------------------------------------------------- 0.19s

Playbook finished: Mon Dec 24 18:25:412018, 1 total tasks.  0:00:00 elapsed.


2.With_flattened
#flatten过滤器可以替代with_flattened,当处理多层嵌套的列表时,列表中所有的嵌套层级都会被拉平
[root@localhost cycle]# cat cycle.5.yml
---
  -name: cycle test5
   hosts: test
   gather_facts: no
   vars:
     dicts:
       - A
       - B
       - [c,D]
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ item }}"
     loop: "{{ dicts | flatten }}"


结果:
[root@localhost cycle]# ansible-playbookcycle.5.yml

PLAY [cycle test5]**************************************************************************************

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item=A) => {
   "msg": "A"
}
ok: [192.168.15.10] => (item=B) => {
   "msg": "B"
}
ok: [192.168.15.10] => (item=c) => {
   "msg": "c"
}
ok: [192.168.15.10] => (item=D) => {
   "msg": "D"
}

PLAY RECAP**********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle------------------------------------------------------------- 0.19s

Playbook finished: Mon Dec 24 18:31:472018, 1 total tasks.  0:00:00 elapsed.


3.With_items
#flatten过滤器(加参数)可以替代with_items,当处理多层嵌套的列表时,只有列表中的第一层会被拉平
[root@localhost cycle]# cat cycle.6.yml
---
  -name: cycle test6
   hosts: test
   gather_facts: no
   vars:
     dicts:
       - A
       - B
       - [c,D]
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ item }}"
     loop: "{{ dicts | flatten(levels=1) }}"


结果:
[root@localhost cycle]# ansible-playbookcycle.6.yml

PLAY [cycle test6] **************************************************************************************

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item=A) => {
   "msg": "A"
}
ok: [192.168.15.10] => (item=B) => {
   "msg": "B"
}
ok: [192.168.15.10] => (item=c) => {
   "msg": "c"
}
ok: [192.168.15.10] => (item=D) => {
   "msg": "D"
}

PLAY RECAP **********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle------------------------------------------------------------- 0.29s

Playbook finished: Mon Dec 24 18:34:312018, 1 total tasks.  0:00:00 elapsed.


#PS  处理下客户问题先。Weblogic真毒~
4.With_indexed_items
#flatten过滤器(加参数),再配合loop_control关键字,可以替代with_indexed_items
#当处理多层嵌套的列表时,只有列表中的第一层会被拉平,flatten过滤器的bug暂且忽略
[root@localhost cycle]# cat cycle.7.yml
---
  -name: cycle test7
   hosts: test
   gather_facts: no
   vars:
     dicts:
       - A
       - B
       - [c,D]
   tasks:
    -name: debug cycle
     debug:
       msg: " {{ index}}--{{ item }}"
     loop: "{{ dicts | flatten(levels=1) }}"
     loop_control:
       index_var: index


结果:
[root@localhost cycle]# ansible-playbookcycle.7.yml

PLAY [cycle test7]**************************************************************************************

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item=A) => {
   "msg": " 0--A"
}
ok: [192.168.15.10] => (item=B) => {
   "msg": " 1--B"
}
ok: [192.168.15.10] => (item=c) => {
   "msg": " 2--c"
}
ok: [192.168.15.10] => (item=D) => {
   "msg": " 3--D"
}

PLAY RECAP**********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0   skipped=0   

debug cycle------------------------------------------------------------- 0.21s

Playbook finished: Mon Dec 24 20:29:572018, 1 total tasks.  0:00:00 elapsed.


“loop_control”关键字可以用于控制循环的行为,比如在循环是获取元素的索引。
“index_var “”loop_control”的一个设置选项,”index_var”可以让我们指定变量,”loop_control”会将元素索引值存放在指定变量中



5.With_togeher
[root@localhost cycle]# cat cycle.8.yml
---
  -name: cycle test8
   hosts: test
   gather_facts: no
   vars:
     testlist1: [ A,B,C,D ]
     testlist2: [ 110,120,911 ]
     testlist3: [ x,y ]
   tasks:
    -name: debug cycle with_together
     debug:
       msg: " {{ item.0 }} - {{ item.1 }} - {{ item.2 }}"
     with_together:
       - "{{ testlist1 }}"
       - "{{ testlist2 }}"
       - "{{ testlist3 }}"
    -name: debug cycle loop+zip_logest
     debug:
       msg: " {{ item.0 }} - {{ item.1 }} - {{ item.2 }}"
     loop: "{{ testlist1 | zip_longest(testlist2,testlist3) | list }}


结果:
[root@localhost cycle]# ansible-playbookcycle.8.yml

PLAY [cycle test8]**************************************************************************************

TASK [debug cycle with_together]************************************************************************
ok: [192.168.15.10] => (item=[u'A', 110,u'x']) => {
   "msg": " A - 110 - x"
}
ok: [192.168.15.10] => (item=[u'B', 120,u'y']) => {
   "msg": " B - 120 - y"
}
ok: [192.168.15.10] => (item=[u'C', 911,None]) => {
   "msg": " C - 911 - "
}
ok: [192.168.15.10] => (item=[u'D',None, None]) => {
   "msg": " D -  -"
}

TASK [debug cycle loop+zip_logest]**********************************************************************
ok: [192.168.15.10] => (item=[u'A', 110,u'x']) => {
   "msg": " A - 110 - x"
}
ok: [192.168.15.10] => (item=[u'B', 120,u'y']) => {
   "msg": " B - 120 - y"
}
ok: [192.168.15.10] => (item=[u'C', 911,None]) => {
   "msg": " C - 911 - "
}
ok: [192.168.15.10] => (item=[u'D',None, None]) => {
   "msg": " D -  -"
}

PLAY RECAP**********************************************************************************************
192.168.15.10              : ok=2    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle with_together----------------------------------------------- 0.25s
debug cycle loop+zip_logest--------------------------------------------- 0.21s

Playbook finished: Mon Dec 24 20:44:422018, 2 total tasks.  0:00:00 elapsed.

示例中同时写出2中方法方便进行比较。
但多个列表使用”with_together”进行对比合并时,如果列表长度不同,这使用最长的列表长度进行对其,由于短列表中元素不足,所以使用空值与长列表中元素进行对齐,zip_longest过滤器也和”with_together”一样,对列表进行组合,但是还需要借助list过滤器,将组合的数据列表化。
可以指定字符代替空值
  - debug:
      msg: "{{ item.0 }} - {{ item.1 }} - {{item.2}}"
loop: "{{ testlist1 | zip_longest(testlist2,testlist3,fillvalue='None') | list }}"

和最短的列表进行对齐
- debug:
      msg: "{{ item.0 }} - {{ item.1 }} - {{item.2}}"
loop: "{{ testlist1 | zip(testlist2,testlist3) | list }}"



6.With_nested/With_cartesian
#product过滤器配合list过滤器,可以替代with_nestedwith_cartesian
[root@localhost cycle]# cat cycle.9.yml
---
  -name: cycle test4
   hosts: test
   gather_facts: no
   vars:
     list1: [ 1,2,3 ]
     list2: [ a,b,c,d ]
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ item.0 }} ----  {{item.1 }}"
     loop: "{{ list1 | product(list2) | list }}"


结果:
[root@localhost cycle]# ansible-playbookcycle.9.yml

PLAY [cycle test4]**************************************************************************************

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item=[1, u'a'])=> {
   "msg": "1 ---- a"
}
ok: [192.168.15.10] => (item=[1, u'b'])=> {
   "msg": "1 ---- b"
}
ok: [192.168.15.10] => (item=[1, u'c'])=> {
   "msg": "1 ---- c"
}
ok: [192.168.15.10] => (item=[1, u'd'])=> {
   "msg": "1 ---- d"
}
ok: [192.168.15.10] => (item=[2, u'a'])=> {
   "msg": "2 ---- a"
}
ok: [192.168.15.10] => (item=[2, u'b'])=> {
   "msg": "2 ---- b"
}
ok: [192.168.15.10] => (item=[2, u'c'])=> {
    "msg": "2 ----  c"
}
ok: [192.168.15.10] => (item=[2, u'd'])=> {
   "msg": "2 ---- d"
}
ok: [192.168.15.10] => (item=[3, u'a'])=> {
   "msg": "3 ---- a"
}
ok: [192.168.15.10] => (item=[3, u'b'])=> {
   "msg": "3 ---- b"
}
ok: [192.168.15.10] => (item=[3, u'c'])=> {
   "msg": "3 ---- c"
}
ok: [192.168.15.10] => (item=[3, u'd'])=> {
   "msg": "3 ---- d"
}

PLAY RECAP **********************************************************************************************
192.168.15.10              : ok=1    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle------------------------------------------------------------- 0.31s

Playbook finished: Mon Dec 24 20:55:192018, 1 total tasks.  0:00:00 elapsed.


7.With_random_choice
#使用random函数可以替代with_random_choice,由于random函数是随机取出列表中的一个值,并不涉及循环操作,所以并不用使用loop关键字。
[root@localhost cycle]# cat cycle.10.yml
---
  -name: cycle test
   hosts: test
   gather_facts: no
   vars:
     list: [a,b,c]
   tasks:
    -name: debug cycle
     debug:
       msg: "{{ list | random }}"
   -  debug:
       msg: "{{ list | random }}"
   -  debug:
       msg: "{{ list | random }}


结果:
[root@localhost cycle]# ansible-playbookcycle.10.yml

PLAY [cycle test]***************************************************************************************

TASK [debug cycle] **************************************************************************************
ok: [192.168.15.10] => {
   "msg": "a"
}

TASK [debug]********************************************************************************************
ok: [192.168.15.10] => {
   "msg": "a"
}

TASK [debug]********************************************************************************************
ok: [192.168.15.10] => {
   "msg": "c"
}

PLAY RECAP**********************************************************************************************
192.168.15.10              : ok=3    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle------------------------------------------------------------- 0.18s
------------------------------------------------------------------------0.16s

Playbook finished: Mon Dec 24 21:06:322018, 2 total tasks.  0:00:00 elapsed.


8.with_dict
#除了上文总结的dict2items过滤器,dictsort过滤器也可以替代with_dict
[root@localhost cycle]# cat cycle.11.yml
---
  -name: cycle test2
   hosts: test
    gather_facts:no
   vars:
     dicts:
       China: 1
       America: 2
       aaa: 3
       bbb: 4
       ccc: 5
   tasks:
    -name: debug cycle dict2items
     debug:
       msg: "{{ item.key }} is no.{{ item.value }}"
     loop: "{{ dicts | dict2items }}"
    -name: debug cycle
     debug:
       msg: "{{ item.0 }} is no.{{ item.1 }}"
     loop: "{{ dicts | dictsort }}"


结果:
[root@localhost cycle]# ansible-playbookcycle.11.yml

PLAY [cycle test2]**************************************************************************************

TASK [debug cycle dict2items]***************************************************************************
ok: [192.168.15.10] => (item={'key':u'China', 'value': 1}) => {
   "msg": "China is no.1"
}
ok: [192.168.15.10] => (item={'key':u'America', 'value': 2}) => {
   "msg": "America is no.2"
}
ok: [192.168.15.10] => (item={'key':u'aaa', 'value': 3}) => {
   "msg": "aaa is no.3"
}
ok: [192.168.15.10] => (item={'key':u'bbb', 'value': 4}) => {
   "msg": "bbb is no.4"
}
ok: [192.168.15.10] => (item={'key':u'ccc', 'value': 5}) => {
   "msg": "ccc is no.5"
}

TASK [debug cycle]**************************************************************************************
ok: [192.168.15.10] => (item=[u'aaa', 3])=> {
   "msg": "aaa is no.3"
}
ok: [192.168.15.10] =>(item=[u'America', 2]) => {
   "msg": "America is no.2"
}
ok: [192.168.15.10] => (item=[u'bbb',4]) => {
   "msg": "bbb is no.4"
}
ok: [192.168.15.10] => (item=[u'ccc',5]) => {
   "msg": "ccc is no.5"
}
ok: [192.168.15.10] => (item=[u'China',1]) => {
   "msg": "China is no.1"
}

PLAY RECAP **********************************************************************************************
192.168.15.10              : ok=2    changed=0   unreachable=0    failed=0    skipped=0  

debug cycle dict2items-------------------------------------------------- 0.26s
debug cycle------------------------------------------------------------- 0.22s

Playbook finished: Mon Dec 24 21:10:402018, 2 total tasks.  0:00:00 elapsed.
  • 发表于 2022-07-14 16:24
  • 阅读 ( 2807 )
  • 分类:Ansible

0 条评论

请先 登录 后评论
乐维君
乐维君

347 篇文章

作家榜 »

  1. 乐维君 347 文章
  2. YOHOHO 14 文章
  3. 机灵小和尚 13 文章
  4. 我是一只小菜鸡 12 文章
  5. 细雨闲花 11 文章
  6. 御前侍卫张五哥 9 文章
  7. 。。。 8 文章
  8. 小黄人 8 文章