【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_nested和with_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.



本文《ansible循环》首发于 乐维论坛,欢迎到访~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容