1. 程式人生 > >【Ansible】ansible迴圈

【Ansible】ansible迴圈

Ansible 迴圈

一、簡單介紹

在ansible2.5之前,大多數人使”with_XXX”型別的關鍵字來操作迴圈,但是從2.6版本開始,官方推薦是”loop”關鍵字代替” with_XXX”。

1.我們先看下一個小例子,使用loop關鍵字進行最簡單的迴圈:

[[email protected] cycle]# cat cycle.1.yml

---

  - name: cycletest

    hosts: test

    gather_facts: no

    tasks:

    - name: debug cycle

      debug:

        msg: 
"{{ item }}" loop: - test1 - test2

 

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:25 2018, 1 total tasks. 0:00:00 elapsed.

例項中所以loop關鍵字,替換之前的with_XXX關鍵字,它們的效果是完全相同的。

2.我們可以使用loop關鍵字和dict外掛代替”with_dict”關鍵字,示例如下:

[[email protected] 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) }}"

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:58 2018, 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 }}"

 結果:

[[email protected] cycle]# ansible-playbook cycle.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:21 2018, 1 total tasks.  0:00:00 elapsed.

 

如上例所示,在使用loop關鍵字操作對於的字典變數users時,並沒有藉助dict外掛,而是使用dict2items的過濾器。

 

二、具體示例

1.With_list

#loop可以替代with_list,當處理巢狀的列表時,列表不會被拉平

[[email protected] 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 }}"

 

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:41 2018, 1 total tasks.  0:00:00 elapsed.
 

  

2.With_flattened

#flatten過濾器可以替代with_flattened,當處理多層巢狀的列表時,列表中所有的巢狀層級都會被拉平

[[email protected] 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 }}"

  

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:47 2018, 1 total tasks.  0:00:00 elapsed.

 

3.With_items

#flatten過濾器(加引數)可以替代with_items,當處理多層巢狀的列表時,只有列表中的第一層會被拉平

[[email protected] 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) }}"

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:31 2018, 1 total tasks.  0:00:00 elapsed.

 

#PS 嗯 處理下客戶問題先。Weblogic真毒~

4.With_indexed_items

#flatten過濾器(加引數),再配合loop_control關鍵字,可以替代with_indexed_items

#當處理多層巢狀的列表時,只有列表中的第一層會被拉平,flatten過濾器的bug暫且忽略

[[email protected] 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

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:57 2018, 1 total tasks.  0:00:00 elapsed.

 

“loop_control”關鍵字可以用於控制迴圈的行為,比如在迴圈是獲取元素的索引。

“index_var “是”loop_control”的一個設定選項,”index_var”可以讓我們指定變數,”loop_control”會將元素索引值存放在指定變數中

 

5.With_togeher

[[email protected] 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 }}

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:42 2018, 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

[[email protected] 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 }}"

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:19 2018, 1 total tasks.  0:00:00 elapsed.

 

7.With_random_choice

#使用random函式可以替代with_random_choice,由於random函式是隨機取出列表中的一個值,並不涉及迴圈操作,所以並不用使用loop關鍵字。

[[email protected] 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 }}

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:32 2018, 2 total tasks.  0:00:00 elapsed.

 

8.with_dict

#除了上文總結的dict2items過濾器,dictsort過濾器也可以替代with_dict

[[email protected] 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 }}"

 

結果:

[[email protected] cycle]# ansible-playbook cycle.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:40 2018, 2 total tasks.  0:00:00 elapsed.